diff options
1014 files changed, 18904 insertions, 5288 deletions
diff --git a/Android.bp b/Android.bp index 8d3b4af82bc8..935b2bb478bb 100644 --- a/Android.bp +++ b/Android.bp @@ -722,7 +722,6 @@ filegroup { "core/java/com/android/internal/util/IndentingPrintWriter.java", "core/java/com/android/internal/util/IState.java", "core/java/com/android/internal/util/MessageUtils.java", - "core/java/com/android/internal/util/Preconditions.java", "core/java/com/android/internal/util/State.java", "core/java/com/android/internal/util/StateMachine.java", "core/java/com/android/internal/util/TrafficStatsConstants.java", diff --git a/ApiDocs.bp b/ApiDocs.bp index 04ddc50a94c4..fbc5c9dc817d 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -65,8 +65,9 @@ stubs_defaults { "test-base/src/**/*.java", ":opt-telephony-srcs", ":opt-net-voip-srcs", - ":core-current-stubs-source", - ":core_public_api_files", + ":art-module-public-api-stubs-source", + ":conscrypt.module.public.api.stubs.source", + ":android_icu4j_public_api_files", "test-mock/src/**/*.java", "test-runner/src/**/*.java", ], diff --git a/StubLibraries.bp b/StubLibraries.bp index bfc1367cceb9..8fd8c907202c 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -47,8 +47,9 @@ stubs_defaults { "core/java/**/*.logtags", ":opt-telephony-srcs", ":opt-net-voip-srcs", - ":core-current-stubs-source", - ":core_public_api_files", + ":art-module-public-api-stubs-source", + ":conscrypt.module.public.api.stubs.source", + ":android_icu4j_public_api_files", ], // TODO(b/147699819): remove below aidl includes. aidl: { diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java index 8c55b50957da..d108f0b698f7 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java @@ -241,10 +241,11 @@ public final class QuotaController extends StateController { + "bgJobCountInMaxPeriod=" + bgJobCountInMaxPeriod + ", " + "sessionCountInWindow=" + sessionCountInWindow + ", " + "inQuotaTime=" + inQuotaTimeElapsed + ", " - + "jobCountExpirationTime=" + jobRateLimitExpirationTimeElapsed + ", " - + "jobCountInRateLimitingWindow=" + jobCountInRateLimitingWindow + ", " - + "sessionCountExpirationTime=" + sessionRateLimitExpirationTimeElapsed + ", " - + "sessionCountInRateLimitingWindow=" + sessionCountInRateLimitingWindow; + + "rateLimitJobCountExpirationTime=" + jobRateLimitExpirationTimeElapsed + ", " + + "rateLimitJobCountWindow=" + jobCountInRateLimitingWindow + ", " + + "rateLimitSessionCountExpirationTime=" + + sessionRateLimitExpirationTimeElapsed + ", " + + "rateLimitSessionCountWindow=" + sessionCountInRateLimitingWindow; } @Override @@ -863,12 +864,19 @@ public final class QuotaController extends StateController { stats.executionTimeInMaxPeriodMs = 0; stats.bgJobCountInMaxPeriod = 0; stats.sessionCountInWindow = 0; - stats.inQuotaTimeElapsed = 0; + if (stats.jobCountLimit == 0 || stats.sessionCountLimit == 0) { + // App won't be in quota until configuration changes. + stats.inQuotaTimeElapsed = Long.MAX_VALUE; + } else { + stats.inQuotaTimeElapsed = 0; + } Timer timer = mPkgTimers.get(userId, packageName); final long nowElapsed = sElapsedRealtimeClock.millis(); stats.expirationTimeElapsed = nowElapsed + MAX_PERIOD_MS; if (timer != null && timer.isActive()) { + // Exclude active sessions from the session count so that new jobs aren't prevented + // from starting due to an app hitting the session limit. stats.executionTimeInWindowMs = stats.executionTimeInMaxPeriodMs = timer.getCurrentDuration(nowElapsed); stats.bgJobCountInWindow = stats.bgJobCountInMaxPeriod = timer.getBgJobCount(); @@ -883,6 +891,10 @@ public final class QuotaController extends StateController { stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, nowElapsed - mMaxExecutionTimeIntoQuotaMs + MAX_PERIOD_MS); } + if (stats.bgJobCountInWindow >= stats.jobCountLimit) { + stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, + nowElapsed + stats.windowSizeMs); + } } List<TimingSession> sessions = mTimingSessions.get(userId, packageName); @@ -1303,6 +1315,13 @@ public final class QuotaController extends StateController { inQuotaTimeElapsed = Math.max(inQuotaTimeElapsed, stats.sessionRateLimitExpirationTimeElapsed); } + if (inQuotaTimeElapsed <= sElapsedRealtimeClock.millis()) { + final long nowElapsed = sElapsedRealtimeClock.millis(); + Slog.wtf(TAG, + "In quota time is " + (nowElapsed - inQuotaTimeElapsed) + "ms old. Now=" + + nowElapsed + ", inQuotaTime=" + inQuotaTimeElapsed + ": " + stats); + inQuotaTimeElapsed = nowElapsed + 5 * MINUTE_IN_MILLIS; + } mInQuotaAlarmListener.addAlarmLocked(userId, packageName, inQuotaTimeElapsed); } @@ -1916,8 +1935,8 @@ public final class QuotaController extends StateController { @GuardedBy("mLock") private void setNextAlarmLocked(long earliestTriggerElapsed) { if (mAlarmQueue.size() > 0) { - final long nextTriggerTimeElapsed = Math.max(earliestTriggerElapsed, - mAlarmQueue.peek().second); + final Pair<Package, Long> alarm = mAlarmQueue.peek(); + final long nextTriggerTimeElapsed = Math.max(earliestTriggerElapsed, alarm.second); // Only schedule the alarm if one of the following is true: // 1. There isn't one currently scheduled // 2. The new alarm is significantly earlier than the previous alarm. If it's @@ -1928,7 +1947,8 @@ public final class QuotaController extends StateController { || nextTriggerTimeElapsed < mTriggerTimeElapsed - 3 * MINUTE_IN_MILLIS || mTriggerTimeElapsed < nextTriggerTimeElapsed) { if (DEBUG) { - Slog.d(TAG, "Scheduling start alarm at " + nextTriggerTimeElapsed); + Slog.d(TAG, "Scheduling start alarm at " + nextTriggerTimeElapsed + + " for app " + alarm.first); } mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextTriggerTimeElapsed, ALARM_TAG_QUOTA_CHECK, this, mHandler); diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 3c1fafbc1495..24728dd8edca 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -110,6 +110,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; +import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.usage.AppIdleHistory.AppUsageHistory; import java.io.File; @@ -1862,10 +1863,15 @@ public class AppStandbyController implements AppStandbyInternal { public List<UserHandle> getValidCrossProfileTargets(String pkg, int userId) { final int uid = mPackageManagerInternal.getPackageUidInternal(pkg, 0, userId); + final AndroidPackage aPkg = mPackageManagerInternal.getPackage(uid); if (uid < 0 - || !mPackageManagerInternal.getPackage(uid).isCrossProfile() + || aPkg == null + || !aPkg.isCrossProfile() || !mCrossProfileAppsInternal .verifyUidHasInteractAcrossProfilePermission(pkg, uid)) { + if (uid >= 0 && aPkg == null) { + Slog.wtf(TAG, "Null package retrieved for UID " + uid); + } return Collections.emptyList(); } return mCrossProfileAppsInternal.getTargetUserProfiles(pkg, userId); diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java index 2746cba76887..d22e998f6cab 100644 --- a/apex/media/framework/java/android/media/MediaParser.java +++ b/apex/media/framework/java/android/media/MediaParser.java @@ -120,7 +120,7 @@ import java.util.UUID; * @Override * public void onTrackDataFound(int i, @NonNull TrackData trackData) { * MediaFormat mediaFormat = trackData.mediaFormat; - * if (videoTrackIndex == -1 && + * if (videoTrackIndex == -1 && * mediaFormat * .getString(MediaFormat.KEY_MIME, /* defaultValue= */ "") * .startsWith("video/")) { @@ -178,7 +178,7 @@ import java.util.UUID; * * private void ensureSpaceInBuffer(int numberOfBytesToRead) { * int requiredLength = bytesWrittenCount + numberOfBytesToRead; - * if (requiredLength > sampleDataBuffer.length) { + * if (requiredLength > sampleDataBuffer.length) { * sampleDataBuffer = Arrays.copyOf(sampleDataBuffer, requiredLength); * } * } diff --git a/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java b/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java index c268ff4291e4..6c25f2849cea 100644 --- a/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java +++ b/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java @@ -38,6 +38,9 @@ public class SdkExtensions { private static final int R_EXTENSION_INT; static { + // Note: when adding more extension versions, the logic that records current + // extension versions when saving a rollback must also be updated. + // At the time of writing this is in RollbackManagerServiceImpl#getExtensionVersions() R_EXTENSION_INT = SystemProperties.getInt("build.version.extensions.r", 0); } diff --git a/api/test-current.txt b/api/test-current.txt index d080d3d946c2..44fb63017ace 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -580,6 +580,7 @@ package android.app.admin { method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(@NonNull android.os.UserHandle); method public boolean isCurrentInputMethodSetByOwner(); method public boolean isDeviceManaged(); + method public boolean isFactoryResetProtectionPolicySupported(); field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED"; field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED"; field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED"; @@ -731,6 +732,11 @@ package android.app.role { method public void onRoleHoldersChanged(@NonNull String, @NonNull android.os.UserHandle); } + public class RoleControllerManager { + method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void isApplicationVisibleForRole(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void isRoleVisible(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + } + public final class RoleManager { method @RequiresPermission("android.permission.OBSERVE_ROLE_HOLDERS") public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); @@ -2888,8 +2894,10 @@ package android.permission { public final class PermissionControllerManager { method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void countPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, @Nullable android.os.Handler); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>); + method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermission(@NonNull String, @NonNull String); method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle); field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 @@ -2898,6 +2906,10 @@ package android.permission { field public static final int REASON_MALWARE = 1; // 0x1 } + public static interface PermissionControllerManager.OnCountPermissionAppsResultCallback { + method public void onCountPermissionApps(int); + } + public static interface PermissionControllerManager.OnGetAppPermissionResultCallback { method public void onGetAppPermissions(@NonNull java.util.List<android.permission.RuntimePermissionPresentationInfo>); } @@ -3684,6 +3696,7 @@ package android.telecom { } public class TelecomManager { + method @NonNull public android.content.Intent createLaunchEmergencyDialerIntent(@Nullable String); method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts(boolean); method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getCurrentTtyMode(); method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getDefaultDialerPackage(@NonNull android.os.UserHandle); @@ -5264,18 +5277,19 @@ package android.widget { package android.window { public final class DisplayAreaInfo implements android.os.Parcelable { - ctor public DisplayAreaInfo(@NonNull android.window.WindowContainerToken, int); + ctor public DisplayAreaInfo(@NonNull android.window.WindowContainerToken, int, int); method public int describeContents(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.DisplayAreaInfo> CREATOR; field @NonNull public final android.content.res.Configuration configuration; field public final int displayId; + field public final int featureId; field @NonNull public final android.window.WindowContainerToken token; } public class DisplayAreaOrganizer extends android.window.WindowOrganizer { ctor public DisplayAreaOrganizer(); - method public void onDisplayAreaAppeared(@NonNull android.window.DisplayAreaInfo); + method public void onDisplayAreaAppeared(@NonNull android.window.DisplayAreaInfo, @NonNull android.view.SurfaceControl); method public void onDisplayAreaVanished(@NonNull android.window.DisplayAreaInfo); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int); field public static final int FEATURE_DEFAULT_TASK_CONTAINER = 1; // 0x1 @@ -5295,7 +5309,7 @@ package android.window { method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static android.window.WindowContainerToken getImeTarget(int); method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]); method @BinderThread public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo); - method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo); + method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo, @NonNull android.view.SurfaceControl); method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo); method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void registerOrganizer(int); @@ -5306,7 +5320,6 @@ package android.window { public final class WindowContainerToken implements android.os.Parcelable { method public int describeContents(); - method @Nullable public android.view.SurfaceControl getLeash(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.WindowContainerToken> CREATOR; } diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 75fc7f714ce3..a93184ff4787 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -34,11 +34,13 @@ #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" #include "idmap2/SysTrace.h" +#include "idmap2/ZipFile.h" #include "utils/String8.h" using android::IPCThreadState; using android::binder::Status; using android::idmap2::BinaryStreamVisitor; +using android::idmap2::GetPackageCrc; using android::idmap2::Idmap; using android::idmap2::IdmapHeader; using android::idmap2::utils::kIdmapCacheDir; @@ -49,6 +51,8 @@ using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask namespace { +constexpr const char* kFrameworkPath = "/system/framework/framework-res.apk"; + Status ok() { return Status::ok(); } @@ -109,8 +113,32 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path, return error("failed to parse idmap header"); } - *_aidl_return = - strcmp(header->GetTargetPath().data(), target_apk_path.data()) == 0 && header->IsUpToDate(); + if (strcmp(header->GetTargetPath().data(), target_apk_path.data()) != 0) { + *_aidl_return = false; + return ok(); + } + + if (target_apk_path != kFrameworkPath) { + *_aidl_return = (bool) header->IsUpToDate(); + } else { + if (!android_crc_) { + // Loading the framework zip can take several milliseconds. Cache the crc of the framework + // resource APK to reduce repeated work during boot. + const auto target_zip = idmap2::ZipFile::Open(target_apk_path); + if (!target_zip) { + return error(base::StringPrintf("failed to open target %s", target_apk_path.c_str())); + } + + const auto target_crc = GetPackageCrc(*target_zip); + if (!target_crc) { + return error(target_crc.GetErrorMessage()); + } + + android_crc_ = *target_crc; + } + + *_aidl_return = (bool) header->IsUpToDate(android_crc_.value()); + } // TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed return ok(); diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h index 0ed55a1bb6a4..55fb5ad07781 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.h +++ b/cmds/idmap2/idmap2d/Idmap2Service.h @@ -46,6 +46,10 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 { const std::string& overlay_apk_path, int32_t fulfilled_policies, bool enforce_overlayable, int32_t user_id, aidl::nullable<std::string>* _aidl_return) override; + + private: + // Cache the crc of the android framework package since the crc cannot change without a reboot. + std::optional<uint32_t> android_crc_; }; } // namespace android::os diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index 2e4836e297ec..77a7b30a230e 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -74,6 +74,7 @@ #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" #include "idmap2/ResourceMapping.h" +#include "idmap2/ZipFile.h" namespace android::idmap2 { @@ -93,6 +94,9 @@ static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVer // terminating null) static constexpr const size_t kIdmapStringLength = 256; +// Retrieves a crc generated using all of the files within the zip that can affect idmap generation. +Result<uint32_t> GetPackageCrc(const ZipFile& zip_info); + class IdmapHeader { public: static std::unique_ptr<const IdmapHeader> FromBinaryStream(std::istream& stream); @@ -129,6 +133,7 @@ class IdmapHeader { // field *must* be incremented. Because of this, we know that if the idmap // header is up-to-date the entire file is up-to-date. Result<Unit> IsUpToDate() const; + Result<Unit> IsUpToDate(uint32_t target_crc_) const; void accept(Visitor* v) const; diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 7f2cd9596c95..706b842b3b47 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -100,7 +100,9 @@ Result<std::string> ReadString(std::istream& stream) { return buf; } -Result<uint32_t> GetCrc(const ZipFile& zip) { +} // namespace + +Result<uint32_t> GetPackageCrc(const ZipFile& zip) { const Result<uint32_t> a = zip.Crc("resources.arsc"); const Result<uint32_t> b = zip.Crc("AndroidManifest.xml"); return a && b @@ -108,8 +110,6 @@ Result<uint32_t> GetCrc(const ZipFile& zip) { : Error("failed to get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc"); } -} // namespace - std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) { std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader()); @@ -130,27 +130,31 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s } Result<Unit> IdmapHeader::IsUpToDate() const { - if (magic_ != kIdmapMagic) { - return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); - } - - if (version_ != kIdmapCurrentVersion) { - return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion); - } - const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path_); if (!target_zip) { return Error("failed to open target %s", GetTargetPath().to_string().c_str()); } - Result<uint32_t> target_crc = GetCrc(*target_zip); + Result<uint32_t> target_crc = GetPackageCrc(*target_zip); if (!target_crc) { return Error("failed to get target crc"); } - if (target_crc_ != *target_crc) { + return IsUpToDate(*target_crc); +} + +Result<Unit> IdmapHeader::IsUpToDate(uint32_t target_crc) const { + if (magic_ != kIdmapMagic) { + return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); + } + + if (version_ != kIdmapCurrentVersion) { + return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion); + } + + if (target_crc_ != target_crc) { return Error("bad target crc: idmap version 0x%08x, file system version 0x%08x", target_crc_, - *target_crc); + target_crc); } const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path_); @@ -158,7 +162,7 @@ Result<Unit> IdmapHeader::IsUpToDate() const { return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str()); } - Result<uint32_t> overlay_crc = GetCrc(*overlay_zip); + Result<uint32_t> overlay_crc = GetPackageCrc(*overlay_zip); if (!overlay_crc) { return Error("failed to get overlay crc"); } @@ -304,13 +308,13 @@ Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& targe header->magic_ = kIdmapMagic; header->version_ = kIdmapCurrentVersion; - Result<uint32_t> crc = GetCrc(*target_zip); + Result<uint32_t> crc = GetPackageCrc(*target_zip); if (!crc) { return Error(crc.GetError(), "failed to get zip CRC for target"); } header->target_crc_ = *crc; - crc = GetCrc(*overlay_zip); + crc = GetPackageCrc(*overlay_zip); if (!crc) { return Error(crc.GetError(), "failed to get zip CRC for overlay"); } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index bb00e23fc95c..674978b50d91 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -426,7 +426,7 @@ message Atom { UserLifecycleEventOccurred user_lifecycle_event_occurred = 265 [(module) = "framework"]; AccessibilityShortcutReported accessibility_shortcut_reported = 266 [(module) = "framework"]; - AccessibilityServiceReported accessibility_service_reported = 267 [(module) = "framework"]; + AccessibilityServiceReported accessibility_service_reported = 267 [(module) = "settings"]; SdkExtensionStatus sdk_extension_status = 354; // StatsdStats tracks platform atoms with ids upto 500. @@ -454,9 +454,9 @@ message Atom { BluetoothActivityInfo bluetooth_activity_info = 10007 [(module) = "framework"]; ProcessMemoryState process_memory_state = 10013 [(module) = "framework"]; SystemElapsedRealtime system_elapsed_realtime = 10014 [(module) = "framework"]; - SystemUptime system_uptime = 10015 [(module) = "framework", (module) = "statsdtest"]; + SystemUptime system_uptime = 10015 [(module) = "framework"]; CpuActiveTime cpu_active_time = 10016 [(module) = "framework", (module) = "statsdtest"]; - CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework", (module) = "statsdtest"]; + CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework"]; DiskSpace disk_space = 10018 [deprecated=true, (module) = "statsdtest"]; RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"]; FullBatteryCapacity full_battery_capacity = 10020 [(module) = "framework"]; @@ -3915,9 +3915,10 @@ message Notification { enum NotificationSection { SECTION_UNKNOWN = 0; SECTION_HEADS_UP = 1; - SECTION_PEOPLE = 2; - SECTION_ALERTING = 3; - SECTION_SILENT = 4; + SECTION_MEDIA_CONTROLS = 2; + SECTION_PEOPLE = 3; + SECTION_ALERTING = 4; + SECTION_SILENT = 5; } optional NotificationSection section = 6; } @@ -9452,7 +9453,7 @@ message UserLifecycleEventOccurred { * Logs when accessibility shortcut clicked. * * Logged from: - * frameworks/base/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java + * frameworks/base/services/accessibility/java/com/android/server/accessibility */ message AccessibilityShortcutReported { // The accessibility feature(including installed a11y service, framework a11y feature, @@ -9472,7 +9473,7 @@ message AccessibilityShortcutReported { * Logs when accessibility service status changed. * * Logged from: - * frameworks/base/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java + * packages/apps/Settings/src/com/android/settings/accessibility */ message AccessibilityServiceReported { // The accessibility service package name. diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 10b1059796a0..8ec0173ce461 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -227,8 +227,8 @@ void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last, } // Check if at least one node was successfully parsed. if (mValues.size() - 1 > firstUidInChainIndex) { - mAttributionChainStartIndex = firstUidInChainIndex; - mAttributionChainEndIndex = mValues.size() - 1; + mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex); + mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1); } parseAnnotations(numAnnotations, firstUidInChainIndex); @@ -249,7 +249,7 @@ void LogEvent::parseIsUidAnnotation(uint8_t annotationType) { } bool isUid = readNextValue<uint8_t>(); - if (isUid) mUidFieldIndex = mValues.size() - 1; + if (isUid) mUidFieldIndex = static_cast<int8_t>(mValues.size() - 1); mValues[mValues.size() - 1].mAnnotations.setUidField(isUid); } @@ -290,7 +290,7 @@ void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) { } const bool exclusiveState = readNextValue<uint8_t>(); - mExclusiveStateFieldIndex = mValues.size() - 1; + mExclusiveStateFieldIndex = static_cast<int8_t>(mValues.size() - 1); mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState); } @@ -408,7 +408,7 @@ bool LogEvent::parseBuffer(uint8_t* buf, size_t len) { parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); break; case ERROR_TYPE: - mErrorBitmask = readNextValue<int32_t>(); + /* mErrorBitmask =*/ readNextValue<int32_t>(); mValid = false; break; default: @@ -577,8 +577,8 @@ bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const { } if (nullptr != indexRange) { - indexRange->first = mAttributionChainStartIndex; - indexRange->second = mAttributionChainEndIndex; + indexRange->first = static_cast<int>(mAttributionChainStartIndex); + indexRange->second = static_cast<int>(mAttributionChainEndIndex); } return true; diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 731b9661067a..53fb5d93e3ac 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -160,7 +160,7 @@ public: // } // Note that atomIndex is 1-indexed. inline int getUidFieldIndex() { - return mUidFieldIndex; + return static_cast<int>(mUidFieldIndex); } // Returns whether this LogEvent has an AttributionChain. @@ -179,7 +179,7 @@ public: // } // Note that atomIndex is 1-indexed. inline int getExclusiveStateFieldIndex() const { - return mExclusiveStateFieldIndex; + return static_cast<int>(mExclusiveStateFieldIndex); } // If a reset state is not sent in the StatsEvent, returns -1. Note that a @@ -212,10 +212,6 @@ public: return mValid; } - int32_t getErrorBitmask() const { - return mErrorBitmask; - } - private: /** * Only use this if copy is absolutely needed. @@ -316,16 +312,16 @@ private: // The pid of the logging client (defaults to -1). int32_t mLogPid = -1; - // Bitmask of errors sent by StatsEvent/AStatsEvent. - int32_t mErrorBitmask = 0; - // Annotations bool mTruncateTimestamp = false; - int mUidFieldIndex = -1; - int mAttributionChainStartIndex = -1; - int mAttributionChainEndIndex = -1; - int mExclusiveStateFieldIndex = -1; int mResetState = -1; + + // Indexes within the FieldValue vector can be stored in 7 bits because + // that's the assumption enforced by the encoding used in FieldValue. + int8_t mUidFieldIndex = -1; + int8_t mAttributionChainStartIndex = -1; + int8_t mAttributionChainEndIndex = -1; + int8_t mExclusiveStateFieldIndex = -1; }; void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut); diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index b809286da5f4..e6144c52c436 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -1691,6 +1691,111 @@ TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) { &buffer); } +TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUid) { + int hostUid = 20; + int isolatedUid = 30; + uint64_t eventTimeNs = 12355; + int atomId = 89; + int field1 = 90; + int field2 = 28; + sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid}); + ConfigKey cfgKey; + StatsdConfig config = MakeConfig(false); + sp<StatsLogProcessor> processor = + CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap); + + shared_ptr<LogEvent> logEvent = makeUidLogEvent(atomId, eventTimeNs, hostUid, field1, field2); + + processor->OnLogEvent(logEvent.get()); + + const vector<FieldValue>* actualFieldValues = &logEvent->getValues(); + EXPECT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value); +} + +TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUid) { + int hostUid = 20; + int isolatedUid = 30; + uint64_t eventTimeNs = 12355; + int atomId = 89; + int field1 = 90; + int field2 = 28; + sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid}); + ConfigKey cfgKey; + StatsdConfig config = MakeConfig(false); + sp<StatsLogProcessor> processor = + CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap); + + shared_ptr<LogEvent> logEvent = + makeUidLogEvent(atomId, eventTimeNs, isolatedUid, field1, field2); + + processor->OnLogEvent(logEvent.get()); + + const vector<FieldValue>* actualFieldValues = &logEvent->getValues(); + EXPECT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value); +} + +TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUidAttributionChain) { + int hostUid = 20; + int isolatedUid = 30; + uint64_t eventTimeNs = 12355; + int atomId = 89; + int field1 = 90; + int field2 = 28; + sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid}); + ConfigKey cfgKey; + StatsdConfig config = MakeConfig(false); + sp<StatsLogProcessor> processor = + CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap); + + shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {hostUid, 200}, + {"tag1", "tag2"}, field1, field2); + + processor->OnLogEvent(logEvent.get()); + + const vector<FieldValue>* actualFieldValues = &logEvent->getValues(); + EXPECT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value); +} + +TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUidAttributionChain) { + int hostUid = 20; + int isolatedUid = 30; + uint64_t eventTimeNs = 12355; + int atomId = 89; + int field1 = 90; + int field2 = 28; + sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid}); + ConfigKey cfgKey; + StatsdConfig config = MakeConfig(false); + sp<StatsLogProcessor> processor = + CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap); + + shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {isolatedUid, 200}, + {"tag1", "tag2"}, field1, field2); + + processor->OnLogEvent(logEvent.get()); + + const vector<FieldValue>* actualFieldValues = &logEvent->getValues(); + EXPECT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value); +} + #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp index c10703c36b98..6bde79f52e33 100644 --- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp +++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp @@ -13,13 +13,15 @@ // limitations under the License. #include "src/anomaly/AnomalyTracker.h" -#include "../metrics/metrics_test_helper.h" #include <gtest/gtest.h> #include <math.h> #include <stdio.h> + #include <vector> +#include "tests/statsd_test_util.h" + using namespace testing; using android::sp; using std::set; diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index c2cfb371d329..a21dc8717776 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -21,9 +21,9 @@ #include <vector> #include "../metrics/metrics_test_helper.h" +#include "FieldValue.h" #include "annotations.h" #include "stats_event.h" -#include "statslog_statsdtest.h" #include "tests/statsd_test_util.h" #ifdef __ANDROID__ @@ -33,207 +33,371 @@ namespace os { namespace statsd { using namespace testing; -using std::make_shared; using std::shared_ptr; using std::vector; -using testing::Contains; /* * Test merge isolated and host uid */ namespace { -int uidAtomTagId = util::CPU_CLUSTER_TIME; -const vector<int> uidAdditiveFields = {3}; -int nonUidAtomTagId = util::SYSTEM_UPTIME; -int timestamp = 1234; -int isolatedUid = 30; -int isolatedAdditiveData = 31; -int isolatedNonAdditiveData = 32; -int hostUid = 20; -int hostAdditiveData = 21; -int hostNonAdditiveData = 22; - -void extractIntoVector(vector<shared_ptr<LogEvent>> events, - vector<vector<int>>& ret) { - ret.clear(); - status_t err; - for (const auto& event : events) { - vector<int> vec; - vec.push_back(event->GetInt(1, &err)); - vec.push_back(event->GetInt(2, &err)); - vec.push_back(event->GetInt(3, &err)); - ret.push_back(vec); - } +const int uidAtomTagId = 100; +const vector<int> additiveFields = {3}; +const int nonUidAtomTagId = 200; +const int timestamp = 1234; +const int isolatedUid1 = 30; +const int isolatedUid2 = 40; +const int isolatedNonAdditiveData = 32; +const int isolatedAdditiveData = 31; +const int hostUid = 20; +const int hostNonAdditiveData = 22; +const int hostAdditiveData = 21; +const int attributionAtomTagId = 300; + +sp<MockUidMap> makeMockUidMap() { + return makeMockUidMapForOneHost(hostUid, {isolatedUid1, isolatedUid2}); } -std::shared_ptr<LogEvent> makeUidLogEvent(uint64_t timestampNs, int uid, int data1, int data2) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, uidAtomTagId); - AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - - AStatsEvent_writeInt32(statsEvent, uid); - AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true); - AStatsEvent_writeInt32(statsEvent, data1); - AStatsEvent_writeInt32(statsEvent, data2); +} // anonymous namespace - std::shared_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - parseStatsEventToLogEvent(statsEvent, logEvent.get()); - return logEvent; +TEST(PullerUtilTest, MergeNoDimension) { + vector<shared_ptr<LogEvent>> data = { + // 30->22->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData, + isolatedAdditiveData), + + // 20->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(1, (int)data.size()); + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value); } -std::shared_ptr<LogEvent> makeNonUidAtomLogEvent(uint64_t timestampNs, int data1) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, nonUidAtomTagId); - AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, data1); - - std::shared_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - parseStatsEventToLogEvent(statsEvent, logEvent.get()); - return logEvent; +TEST(PullerUtilTest, MergeWithDimension) { + vector<shared_ptr<LogEvent>> data = { + // 30->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 20->32->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData, + hostAdditiveData), + + // 20->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value); } -} // anonymous namespace - -TEST(puller_util, MergeNoDimension) { - vector<shared_ptr<LogEvent>> inputData; - - // 30->22->31 - inputData.push_back( - makeUidLogEvent(timestamp, isolatedUid, hostNonAdditiveData, isolatedAdditiveData)); - - // 20->22->21 - inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData)); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields); - - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 22, 52}; - EXPECT_EQ(1, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); +TEST(PullerUtilTest, NoMergeHostUidOnly) { + vector<shared_ptr<LogEvent>> data = { + // 20->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 20->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value); } -TEST(puller_util, MergeWithDimension) { - vector<shared_ptr<LogEvent>> inputData; - - // 30->32->31 - inputData.push_back( - makeUidLogEvent(timestamp, isolatedUid, isolatedNonAdditiveData, isolatedAdditiveData)); +TEST(PullerUtilTest, IsolatedUidOnly) { + vector<shared_ptr<LogEvent>> data = { + // 30->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData, + isolatedAdditiveData), - // 20->32->21 - inputData.push_back( - makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, hostAdditiveData)); + // 30->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData, + hostAdditiveData), + }; - // 20->22->21 - inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData)); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields); - - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 22, 21}; - vector<int> expectedV2 = {20, 32, 52}; - EXPECT_EQ(2, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); - EXPECT_THAT(actual, Contains(expectedV2)); -} + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); -TEST(puller_util, NoMergeHostUidOnly) { - vector<shared_ptr<LogEvent>> inputData; + ASSERT_EQ(2, (int)data.size()); // 20->32->31 - inputData.push_back( - makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, isolatedAdditiveData)); + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value); // 20->22->21 - inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData)); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields); - - // 20->32->31 - // 20->22->21 - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 32, 31}; - vector<int> expectedV2 = {20, 22, 21}; - EXPECT_EQ(2, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); - EXPECT_THAT(actual, Contains(expectedV2)); + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value); } -TEST(puller_util, IsolatedUidOnly) { - vector<shared_ptr<LogEvent>> inputData; +TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUid) { + vector<shared_ptr<LogEvent>> data = { + // 30->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData, + isolatedAdditiveData), - // 30->32->31 - inputData.push_back( - makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, isolatedAdditiveData)); + // 31->32->21 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData, + hostAdditiveData), - // 30->22->21 - inputData.push_back(makeUidLogEvent(timestamp, hostUid, hostNonAdditiveData, hostAdditiveData)); + // 20->32->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData, + hostAdditiveData), + }; - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))).WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields); + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); - // 20->32->31 - // 20->22->21 - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 32, 31}; - vector<int> expectedV2 = {20, 22, 21}; - EXPECT_EQ(2, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); - EXPECT_THAT(actual, Contains(expectedV2)); + ASSERT_EQ(1, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData, + actualFieldValues->at(2).mValue.int_value); } -TEST(puller_util, MultipleIsolatedUidToOneHostUid) { - vector<shared_ptr<LogEvent>> inputData; +TEST(PullerUtilTest, NoNeedToMerge) { + vector<shared_ptr<LogEvent>> data = { + // 32->31 + CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, isolatedNonAdditiveData, + isolatedAdditiveData), - // 30->32->31 - inputData.push_back( - makeUidLogEvent(timestamp, isolatedUid, isolatedNonAdditiveData, isolatedAdditiveData)); + // 22->21 + CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, hostNonAdditiveData, + hostAdditiveData), - // 31->32->21 - inputData.push_back( - makeUidLogEvent(timestamp, isolatedUid + 1, isolatedNonAdditiveData, hostAdditiveData)); + }; - // 20->32->21 - inputData.push_back( - makeUidLogEvent(timestamp, hostUid, isolatedNonAdditiveData, hostAdditiveData)); + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, nonUidAtomTagId, {} /*no additive fields*/); - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(Return(hostUid)); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId, uidAdditiveFields); + ASSERT_EQ(2, (int)data.size()); - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 32, 73}; - EXPECT_EQ(1, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(2, actualFieldValues->size()); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(1).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(2, actualFieldValues->size()); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(1).mValue.int_value); } -TEST(puller_util, NoNeedToMerge) { - vector<shared_ptr<LogEvent>> inputData; +TEST(PullerUtilTest, MergeNoDimensionAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 30->tag1->400->tag2->22->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, isolatedAdditiveData), + + // 20->tag1->400->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(1, (int)data.size()); + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(5).mValue.int_value); +} - // 32 - inputData.push_back(makeNonUidAtomLogEvent(timestamp, isolatedNonAdditiveData)); +TEST(PullerUtilTest, MergeWithDimensionAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 200->tag1->30->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, isolatedUid1}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 200->tag1->20->tag2->32->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid}, + {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData), + + // 200->tag1->20->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value); +} - // 22 - inputData.push_back(makeNonUidAtomLogEvent(timestamp, hostNonAdditiveData)); +TEST(PullerUtilTest, NoMergeHostUidOnlyAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 20->tag1->400->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 20->tag1->400->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value); +} - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, nonUidAtomTagId, {} /*no additive fields*/); +TEST(PullerUtilTest, IsolatedUidOnlyAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 30->tag1->400->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 30->tag1->400->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + // 20->tag1->400->tag2->32->31 + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value); + + // 20->tag1->400->tag2->22->21 + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value); +} - EXPECT_EQ(2, (int)inputData.size()); +TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUidAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 30->tag1->400->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 31->tag1->400->tag2->32->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid2, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData), + + // 20->tag1->400->tag2->32->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(1, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData, + actualFieldValues->at(5).mValue.int_value); } } // namespace statsd diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h index be410b10d43b..46ef0f613bbe 100644 --- a/cmds/statsd/tests/metrics/metrics_test_helper.h +++ b/cmds/statsd/tests/metrics/metrics_test_helper.h @@ -48,12 +48,6 @@ public: void(const ConfigKey& configKey, wp<PullUidProvider> provider)); }; -class MockUidMap : public UidMap { - public: - MOCK_CONST_METHOD1(getHostUidOrSelf, int(int uid)); - MOCK_CONST_METHOD1(getAppUid, std::set<int32_t>(const string& package)); -}; - HashableDimensionKey getMockedDimensionKey(int tagId, int key, std::string value); MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, std::string value); diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 7216e1d8cc8e..2315fd7243bc 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -563,6 +563,48 @@ shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) { return logEvent; } +shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1, + int data2) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); + + AStatsEvent_writeInt32(statsEvent, uid); + AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true); + AStatsEvent_writeInt32(statsEvent, data1); + AStatsEvent_writeInt32(statsEvent, data2); + + shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); + return logEvent; +} + +shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs, + const vector<int>& uids, const vector<string>& tags, + int data1, int data2) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); + + writeAttribution(statsEvent, uids, tags); + AStatsEvent_writeInt32(statsEvent, data1); + AStatsEvent_writeInt32(statsEvent, data2); + + shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); + return logEvent; +} + +sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids) { + sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); + EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>()); + for (const int isolatedUid : isolatedUids) { + EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid)); + } + + return uidMap; +} + std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( uint64_t timestampNs, const android::view::DisplayStateEnum state) { AStatsEvent* statsEvent = AStatsEvent_obtain(); @@ -878,8 +920,7 @@ std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, co sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs, const StatsdConfig& config, const ConfigKey& key, const shared_ptr<IPullAtomCallback>& puller, - const int32_t atomTag) { - sp<UidMap> uidMap = new UidMap(); + const int32_t atomTag, const sp<UidMap> uidMap) { sp<StatsPullerManager> pullerManager = new StatsPullerManager(); if (puller != nullptr) { pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {}, diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index 4d68ea2ecb79..dc012c5381eb 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -17,6 +17,7 @@ #include <aidl/android/os/BnPullAtomCallback.h> #include <aidl/android/os/IPullAtomCallback.h> #include <aidl/android/os/IPullAtomResultReceiver.h> +#include <gmock/gmock.h> #include <gtest/gtest.h> #include "frameworks/base/cmds/statsd/src/stats_log.pb.h" @@ -24,6 +25,7 @@ #include "src/StatsLogProcessor.h" #include "src/hash.h" #include "src/logd/LogEvent.h" +#include "src/packages/UidMap.h" #include "src/stats_log_util.h" #include "stats_event.h" #include "statslog_statsdtest.h" @@ -32,6 +34,7 @@ namespace android { namespace os { namespace statsd { +using namespace testing; using ::aidl::android::os::BnPullAtomCallback; using ::aidl::android::os::IPullAtomCallback; using ::aidl::android::os::IPullAtomResultReceiver; @@ -44,6 +47,12 @@ const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED; enum BucketSplitEvent { APP_UPGRADE, BOOT_COMPLETE }; +class MockUidMap : public UidMap { +public: + MOCK_METHOD(int, getHostUidOrSelf, (int uid), (const)); + MOCK_METHOD(std::set<int32_t>, getAppUid, (const string& package), (const)); +}; + // Converts a ProtoOutputStream to a StatsLogReport proto. StatsLogReport outputStreamToProto(ProtoOutputStream* proto); @@ -212,6 +221,15 @@ std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs); +std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1, + int data2); + +std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs, + const vector<int>& uids, + const vector<string>& tags, int data1, int data2); + +sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids); + // Create log event for screen state changed. std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( uint64_t timestampNs, const android::view::DisplayStateEnum state); @@ -293,7 +311,8 @@ std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, co sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs, const StatsdConfig& config, const ConfigKey& key, const shared_ptr<IPullAtomCallback>& puller = nullptr, - const int32_t atomTag = 0 /*for puller only*/); + const int32_t atomTag = 0 /*for puller only*/, + const sp<UidMap> = new UidMap()); // Util function to sort the log events by timestamp. void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events); diff --git a/cmds/statsd/tools/localtools/Android.bp b/cmds/statsd/tools/localtools/Android.bp index 75a57a3f3068..69a43a8f4712 100644 --- a/cmds/statsd/tools/localtools/Android.bp +++ b/cmds/statsd/tools/localtools/Android.bp @@ -11,9 +11,8 @@ java_binary_host { ], } -java_binary_host { - name: "statsd_testdrive", - manifest: "testdrive_manifest.txt", +java_library_host { + name: "statsd_testdrive_lib", srcs: [ "src/com/android/statsd/shelltools/testdrive/*.java", "src/com/android/statsd/shelltools/Utils.java", @@ -22,4 +21,26 @@ java_binary_host { "platformprotos", "guava", ], -}
\ No newline at end of file +} + + +java_binary_host { + name: "statsd_testdrive", + manifest: "testdrive_manifest.txt", + static_libs: [ + "statsd_testdrive_lib", + ], +} + +java_test_host { + name: "statsd_testdrive_test", + test_suites: ["general-tests"], + srcs: ["test/com/android/statsd/shelltools/testdrive/*.java"], + static_libs: [ + "statsd_testdrive_lib", + "junit", + "platformprotos", + "guava", + ], +} + diff --git a/cmds/statsd/tools/localtools/TEST_MAPPING b/cmds/statsd/tools/localtools/TEST_MAPPING new file mode 100644 index 000000000000..7c8a3db5c610 --- /dev/null +++ b/cmds/statsd/tools/localtools/TEST_MAPPING @@ -0,0 +1,8 @@ +{ + "presubmit": [ + { + "name": "statsd_testdrive_test", + "host": true + } + ] +} diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java index 2909048da7ea..6a74480b505e 100644 --- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java +++ b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java @@ -229,4 +229,56 @@ public class Utils { } return null; } + + /** + * Returns ANDROID_SERIAL environment variable, or null if that is undefined or unavailable. + * @param logger Destination of error messages. + * @return String value of ANDROID_SERIAL environment variable, or null. + */ + public static String getDefaultDevice(Logger logger) { + try { + return System.getenv("ANDROID_SERIAL"); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Failed to check ANDROID_SERIAL environment variable.", + ex); + } + return null; + } + + /** + * Returns the device to use if one can be deduced, or null. + * @param device Command-line specified device, or null. + * @param connectedDevices List of all connected devices. + * @param defaultDevice Environment-variable specified device, or null. + * @param logger Destination of error messages. + * @return Device to use, or null. + */ + public static String chooseDevice(String device, List<String> connectedDevices, + String defaultDevice, Logger logger) { + if (connectedDevices == null || connectedDevices.isEmpty()) { + logger.severe("No connected device."); + return null; + } + if (device != null) { + if (connectedDevices.contains(device)) { + return device; + } + logger.severe("Device not connected: " + device); + return null; + } + if (connectedDevices.size() == 1) { + return connectedDevices.get(0); + } + if (defaultDevice != null) { + if (connectedDevices.contains(defaultDevice)) { + return defaultDevice; + } else { + logger.severe("ANDROID_SERIAL device is not connected: " + defaultDevice); + return null; + } + } + logger.severe("More than one device is connected. Choose one" + + " with -s DEVICE_SERIAL or environment variable ANDROID_SERIAL."); + return null; + } } diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java index 7db514180b9a..ec3c7df7bfba 100644 --- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java +++ b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java @@ -27,7 +27,6 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.List; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -112,17 +111,9 @@ public class LocalDrive { } List<String> connectedDevices = Utils.getDeviceSerials(sLogger); - if (connectedDevices == null || connectedDevices.size() == 0) { - sLogger.log(Level.SEVERE, "No device connected."); - return; - } - if (connectedDevices.size() == 1 && deviceSerial == null) { - deviceSerial = connectedDevices.get(0); - } - + deviceSerial = Utils.chooseDevice(deviceSerial, connectedDevices, + Utils.getDefaultDevice(sLogger), sLogger); if (deviceSerial == null) { - sLogger.log(Level.SEVERE, "More than one devices connected. Please specify" - + " with -s DEVICE_SERIAL"); return; } diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java index 54a744b654cb..a97f132a2d5f 100644 --- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java +++ b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java @@ -15,6 +15,7 @@ */ package com.android.statsd.shelltools.testdrive; +import com.android.internal.os.StatsdConfigProto; import com.android.internal.os.StatsdConfigProto.AtomMatcher; import com.android.internal.os.StatsdConfigProto.EventMetric; import com.android.internal.os.StatsdConfigProto.FieldFilter; @@ -24,11 +25,13 @@ import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher; import com.android.internal.os.StatsdConfigProto.StatsdConfig; import com.android.internal.os.StatsdConfigProto.TimeUnit; import com.android.os.AtomsProto.Atom; +import com.android.os.StatsLog; import com.android.os.StatsLog.ConfigMetricsReport; import com.android.os.StatsLog.ConfigMetricsReportList; import com.android.os.StatsLog.StatsLogReport; import com.android.statsd.shelltools.Utils; +import com.google.common.annotations.VisibleForTesting; import com.google.common.io.Files; import java.io.File; @@ -39,6 +42,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; @@ -73,179 +77,319 @@ public class TestDrive { }; private static final Logger LOGGER = Logger.getLogger(TestDrive.class.getName()); - private String mAdditionalAllowedPackage; - private String mDeviceSerial; - private final Set<Long> mTrackedMetrics = new HashSet<>(); + @VisibleForTesting + String mDeviceSerial = null; + @VisibleForTesting + Dumper mDumper = new BasicDumper(); public static void main(String[] args) { - TestDrive testDrive = new TestDrive(); - Set<Integer> trackedAtoms = new HashSet<>(); + final Configuration configuration = new Configuration(); + final TestDrive testDrive = new TestDrive(); Utils.setUpLogger(LOGGER, false); - String remoteConfigPath = null; - if (args.length < 1) { - LOGGER.log(Level.SEVERE, "Usage: ./test_drive [-p additional_allowed_package] " - + "[-s DEVICE_SERIAL_NUMBER]" - + "<atomId1> <atomId2> ... <atomIdN>"); + if (!testDrive.processArgs(configuration, args, + Utils.getDeviceSerials(LOGGER), Utils.getDefaultDevice(LOGGER))) { return; } - List<String> connectedDevices = Utils.getDeviceSerials(LOGGER); - if (connectedDevices == null || connectedDevices.size() == 0) { - LOGGER.log(Level.SEVERE, "No device connected."); - return; + final ConfigMetricsReportList reports = testDrive.testDriveAndGetReports( + configuration.createConfig(), configuration.hasPulledAtoms(), + configuration.hasPushedAtoms()); + if (reports != null) { + configuration.dumpMetrics(reports, testDrive.mDumper); } + } - int arg_index = 0; - while (arg_index < args.length) { - String arg = args[arg_index]; - if (arg.equals("-p")) { - testDrive.mAdditionalAllowedPackage = args[++arg_index]; - } else if (arg.equals("-s")) { - testDrive.mDeviceSerial = args[++arg_index]; - } else { - break; - } - arg_index++; + boolean processArgs(Configuration configuration, String[] args, List<String> connectedDevices, + String defaultDevice) { + if (args.length < 1) { + LOGGER.severe("Usage: ./test_drive [-one] " + + "[-p additional_allowed_package] " + + "[-s DEVICE_SERIAL_NUMBER] " + + "<atomId1> <atomId2> ... <atomIdN>"); + return false; } - if (connectedDevices.size() == 1 && testDrive.mDeviceSerial == null) { - testDrive.mDeviceSerial = connectedDevices.get(0); + int first_arg = 0; + // Consume all flags, which must precede all atoms + for (; first_arg < args.length; ++first_arg) { + String arg = args[first_arg]; + int remaining_args = args.length - first_arg; + if (remaining_args >= 2 && arg.equals("-one")) { + LOGGER.info("Creating one event metric to catch all pushed atoms."); + configuration.mOnePushedAtomEvent = true; + } else if (remaining_args >= 2 && arg.equals("-terse")) { + LOGGER.info("Terse output format."); + mDumper = new TerseDumper(); + } else if (remaining_args >= 3 && arg.equals("-p")) { + configuration.mAdditionalAllowedPackage = args[++first_arg]; + } else if (remaining_args >= 3 && arg.equals("-s")) { + mDeviceSerial = args[++first_arg]; + } else { + break; // Found the atom list + } } - if (testDrive.mDeviceSerial == null) { - LOGGER.log(Level.SEVERE, "More than one devices connected. Please specify" - + " with -s DEVICE_SERIAL"); - return; + mDeviceSerial = Utils.chooseDevice(mDeviceSerial, connectedDevices, defaultDevice, LOGGER); + if (mDeviceSerial == null) { + return false; } - for (int i = arg_index; i < args.length; i++) { + for ( ; first_arg < args.length; ++first_arg) { + String atom = args[first_arg]; try { - int atomId = Integer.valueOf(args[i]); - if (Atom.getDescriptor().findFieldByNumber(atomId) == null) { - LOGGER.log(Level.SEVERE, "No such atom found: " + args[i]); - continue; - } - trackedAtoms.add(atomId); + configuration.addAtom(Integer.valueOf(atom)); } catch (NumberFormatException e) { - LOGGER.log(Level.SEVERE, "Bad atom id provided: " + args[i]); - continue; + LOGGER.severe("Bad atom id provided: " + atom); } } + return configuration.hasPulledAtoms() || configuration.hasPushedAtoms(); + } + + private ConfigMetricsReportList testDriveAndGetReports(StatsdConfig config, + boolean hasPulledAtoms, boolean hasPushedAtoms) { + if (config == null) { + LOGGER.severe("Failed to create valid config."); + return null; + } + + String remoteConfigPath = null; try { - StatsdConfig config = testDrive.createConfig(trackedAtoms); - if (config == null) { - LOGGER.log(Level.SEVERE, "Failed to create valid config."); - return; - } - remoteConfigPath = testDrive.pushConfig(config, testDrive.mDeviceSerial); - LOGGER.info("Pushed the following config to statsd:"); + remoteConfigPath = pushConfig(config, mDeviceSerial); + LOGGER.info("Pushed the following config to statsd on device '" + mDeviceSerial + + "':"); LOGGER.info(config.toString()); - if (!hasPulledAtom(trackedAtoms)) { + if (hasPushedAtoms) { + LOGGER.info("Now please play with the device to trigger the event."); + } + if (!hasPulledAtoms) { LOGGER.info( - "Now please play with the device to trigger the event. All events should " - + "be dumped after 1 min ..."); + "All events should be dumped after 1 min ..."); Thread.sleep(60_000); } else { - LOGGER.info("Now wait for 1.5 minutes ..."); + LOGGER.info("All events should be dumped after 1.5 minutes ..."); Thread.sleep(15_000); - Utils.logAppBreadcrumb(0, 0, LOGGER, testDrive.mDeviceSerial); + Utils.logAppBreadcrumb(0, 0, LOGGER, mDeviceSerial); Thread.sleep(75_000); } - testDrive.dumpMetrics(); + return Utils.getReportList(CONFIG_ID, true, false, LOGGER, + mDeviceSerial); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Failed to test drive: " + e.getMessage(), e); } finally { - testDrive.removeConfig(testDrive.mDeviceSerial); + removeConfig(mDeviceSerial); if (remoteConfigPath != null) { try { Utils.runCommand(null, LOGGER, - "adb", "-s", testDrive.mDeviceSerial, "shell", "rm", remoteConfigPath); + "adb", "-s", mDeviceSerial, "shell", "rm", + remoteConfigPath); } catch (Exception e) { LOGGER.log(Level.WARNING, "Unable to remove remote config file: " + remoteConfigPath, e); } } } + return null; } - private void dumpMetrics() throws Exception { - ConfigMetricsReportList reportList = Utils.getReportList(CONFIG_ID, true, false, LOGGER, - mDeviceSerial); - // We may get multiple reports. Take the last one. - ConfigMetricsReport report = reportList.getReports(reportList.getReportsCount() - 1); - for (StatsLogReport statsLog : report.getMetricsList()) { - if (mTrackedMetrics.contains(statsLog.getMetricId())) { - LOGGER.info(statsLog.toString()); + static class Configuration { + boolean mOnePushedAtomEvent = false; + @VisibleForTesting + Set<Integer> mPushedAtoms = new TreeSet<>(); + @VisibleForTesting + Set<Integer> mPulledAtoms = new TreeSet<>(); + @VisibleForTesting + String mAdditionalAllowedPackage = null; + private final Set<Long> mTrackedMetrics = new HashSet<>(); + + private void dumpMetrics(ConfigMetricsReportList reportList, Dumper dumper) { + // We may get multiple reports. Take the last one. + ConfigMetricsReport report = reportList.getReports(reportList.getReportsCount() - 1); + for (StatsLogReport statsLog : report.getMetricsList()) { + if (isTrackedMetric(statsLog.getMetricId())) { + LOGGER.info(statsLog.toString()); + dumper.dump(statsLog); + } } } - } - private StatsdConfig createConfig(Set<Integer> atomIds) { - long metricId = METRIC_ID_BASE; - long atomMatcherId = ATOM_MATCHER_ID_BASE; + boolean isTrackedMetric(long metricId) { + return mTrackedMetrics.contains(metricId); + } - ArrayList<String> allowedSources = new ArrayList<>(); - Collections.addAll(allowedSources, ALLOWED_LOG_SOURCES); - if (mAdditionalAllowedPackage != null) { - allowedSources.add(mAdditionalAllowedPackage); + static boolean isPulledAtom(int atomId) { + return atomId >= PULL_ATOM_START && atomId <= MAX_PLATFORM_ATOM_TAG + || atomId >= VENDOR_PULLED_ATOM_START_TAG; } - StatsdConfig.Builder builder = StatsdConfig.newBuilder(); - builder - .addAllAllowedLogSource(allowedSources) - .addAllDefaultPullPackages(Arrays.asList(DEFAULT_PULL_SOURCES)) - .addPullAtomPackages(PullAtomPackages.newBuilder() - .setAtomId(Atom.GPU_STATS_GLOBAL_INFO_FIELD_NUMBER) - .addPackages("AID_GPU_SERVICE")) - .addPullAtomPackages(PullAtomPackages.newBuilder() - .setAtomId(Atom.GPU_STATS_APP_INFO_FIELD_NUMBER) - .addPackages("AID_GPU_SERVICE")) - .addPullAtomPackages(PullAtomPackages.newBuilder() - .setAtomId(Atom.TRAIN_INFO_FIELD_NUMBER) - .addPackages("AID_STATSD")) - .setHashStringsInMetricReport(false); - - if (hasPulledAtom(atomIds)) { - builder.addAtomMatcher( - createAtomMatcher( - Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER, APP_BREADCRUMB_MATCHER_ID)); + void addAtom(Integer atom) { + if (Atom.getDescriptor().findFieldByNumber(atom) == null) { + LOGGER.severe("No such atom found: " + atom); + return; + } + if (isPulledAtom(atom)) { + mPulledAtoms.add(atom); + } else { + mPushedAtoms.add(atom); + } } - for (int atomId : atomIds) { - if (isPulledAtom(atomId)) { + private boolean hasPulledAtoms() { + return !mPulledAtoms.isEmpty(); + } + + private boolean hasPushedAtoms() { + return !mPushedAtoms.isEmpty(); + } + + StatsdConfig createConfig() { + long metricId = METRIC_ID_BASE; + long atomMatcherId = ATOM_MATCHER_ID_BASE; + + StatsdConfig.Builder builder = baseBuilder(); + + if (hasPulledAtoms()) { + builder.addAtomMatcher( + createAtomMatcher( + Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER, + APP_BREADCRUMB_MATCHER_ID)); + } + + for (int atomId : mPulledAtoms) { builder.addAtomMatcher(createAtomMatcher(atomId, atomMatcherId)); GaugeMetric.Builder gaugeMetricBuilder = GaugeMetric.newBuilder(); gaugeMetricBuilder - .setId(metricId) - .setWhat(atomMatcherId) - .setTriggerEvent(APP_BREADCRUMB_MATCHER_ID) - .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true).build()) - .setBucket(TimeUnit.ONE_MINUTE) - .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES) - .setMaxNumGaugeAtomsPerBucket(100); + .setId(metricId) + .setWhat(atomMatcherId) + .setTriggerEvent(APP_BREADCRUMB_MATCHER_ID) + .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true).build()) + .setBucket(TimeUnit.ONE_MINUTE) + .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES) + .setMaxNumGaugeAtomsPerBucket(100); builder.addGaugeMetric(gaugeMetricBuilder.build()); - } else { + atomMatcherId++; + mTrackedMetrics.add(metricId++); + } + + // A simple atom matcher for each pushed atom. + List<AtomMatcher> simpleAtomMatchers = new ArrayList<>(); + for (int atomId : mPushedAtoms) { + final AtomMatcher atomMatcher = createAtomMatcher(atomId, atomMatcherId++); + simpleAtomMatchers.add(atomMatcher); + builder.addAtomMatcher(atomMatcher); + } + + if (mOnePushedAtomEvent) { + // Create a union event metric, using an matcher that matches all pulled atoms. + AtomMatcher unionAtomMatcher = createUnionMatcher(simpleAtomMatchers, + atomMatcherId); + builder.addAtomMatcher(unionAtomMatcher); EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder(); - eventMetricBuilder - .setId(metricId) - .setWhat(atomMatcherId); + eventMetricBuilder.setId(metricId).setWhat(unionAtomMatcher.getId()); builder.addEventMetric(eventMetricBuilder.build()); - builder.addAtomMatcher(createAtomMatcher(atomId, atomMatcherId)); + mTrackedMetrics.add(metricId++); + } else { + // Create multiple event metrics, one per pulled atom. + for (AtomMatcher atomMatcher : simpleAtomMatchers) { + EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder(); + eventMetricBuilder + .setId(metricId) + .setWhat(atomMatcher.getId()); + builder.addEventMetric(eventMetricBuilder.build()); + mTrackedMetrics.add(metricId++); + } } - atomMatcherId++; - mTrackedMetrics.add(metricId++); + + return builder.build(); + } + + private static AtomMatcher createAtomMatcher(int atomId, long matcherId) { + AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder(); + atomMatcherBuilder + .setId(matcherId) + .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder().setAtomId(atomId)); + return atomMatcherBuilder.build(); + } + + private AtomMatcher createUnionMatcher(List<AtomMatcher> simpleAtomMatchers, + long atomMatcherId) { + AtomMatcher.Combination.Builder combinationBuilder = + AtomMatcher.Combination.newBuilder(); + combinationBuilder.setOperation(StatsdConfigProto.LogicalOperation.OR); + for (AtomMatcher matcher : simpleAtomMatchers) { + combinationBuilder.addMatcher(matcher.getId()); + } + AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder(); + atomMatcherBuilder.setId(atomMatcherId).setCombination(combinationBuilder.build()); + return atomMatcherBuilder.build(); + } + + private StatsdConfig.Builder baseBuilder() { + ArrayList<String> allowedSources = new ArrayList<>(); + Collections.addAll(allowedSources, ALLOWED_LOG_SOURCES); + if (mAdditionalAllowedPackage != null) { + allowedSources.add(mAdditionalAllowedPackage); + } + return StatsdConfig.newBuilder() + .addAllAllowedLogSource(allowedSources) + .addAllDefaultPullPackages(Arrays.asList(DEFAULT_PULL_SOURCES)) + .addPullAtomPackages(PullAtomPackages.newBuilder() + .setAtomId(Atom.GPU_STATS_GLOBAL_INFO_FIELD_NUMBER) + .addPackages("AID_GPU_SERVICE")) + .addPullAtomPackages(PullAtomPackages.newBuilder() + .setAtomId(Atom.GPU_STATS_APP_INFO_FIELD_NUMBER) + .addPackages("AID_GPU_SERVICE")) + .addPullAtomPackages(PullAtomPackages.newBuilder() + .setAtomId(Atom.TRAIN_INFO_FIELD_NUMBER) + .addPackages("AID_STATSD")) + .setHashStringsInMetricReport(false); + } + } + + interface Dumper { + void dump(StatsLogReport report); + } + + static class BasicDumper implements Dumper { + @Override + public void dump(StatsLogReport report) { + System.out.println(report.toString()); } - return builder.build(); } - private static AtomMatcher createAtomMatcher(int atomId, long matcherId) { - AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder(); - atomMatcherBuilder - .setId(matcherId) - .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder().setAtomId(atomId)); - return atomMatcherBuilder.build(); + static class TerseDumper extends BasicDumper { + @Override + public void dump(StatsLogReport report) { + if (report.hasGaugeMetrics()) { + dumpGaugeMetrics(report); + } + if (report.hasEventMetrics()) { + dumpEventMetrics(report); + } + } + void dumpEventMetrics(StatsLogReport report) { + final List<StatsLog.EventMetricData> data = report.getEventMetrics().getDataList(); + if (data.isEmpty()) { + return; + } + long firstTimestampNanos = data.get(0).getElapsedTimestampNanos(); + for (StatsLog.EventMetricData event : data) { + final double deltaSec = (event.getElapsedTimestampNanos() - firstTimestampNanos) + / 1e9; + System.out.println( + String.format("+%.3fs: %s", deltaSec, event.getAtom().toString())); + } + } + void dumpGaugeMetrics(StatsLogReport report) { + final List<StatsLog.GaugeMetricData> data = report.getGaugeMetrics().getDataList(); + if (data.isEmpty()) { + return; + } + for (StatsLog.GaugeMetricData gauge : data) { + System.out.println(gauge.toString()); + } + } } private static String pushConfig(StatsdConfig config, String deviceSerial) @@ -267,21 +411,7 @@ public class TestDrive { Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial, "shell", Utils.CMD_REMOVE_CONFIG, String.valueOf(CONFIG_ID)); } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Failed to remove config: " + e.getMessage()); - } - } - - private static boolean isPulledAtom(int atomId) { - return atomId >= PULL_ATOM_START && atomId <= MAX_PLATFORM_ATOM_TAG - || atomId >= VENDOR_PULLED_ATOM_START_TAG; - } - - private static boolean hasPulledAtom(Set<Integer> atoms) { - for (Integer i : atoms) { - if (isPulledAtom(i)) { - return true; - } + LOGGER.severe("Failed to remove config: " + e.getMessage()); } - return false; } } diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java new file mode 100644 index 000000000000..b1cc60f74993 --- /dev/null +++ b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.statsd.shelltools.testdrive; + +import static org.junit.Assert.assertArrayEquals; +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 com.android.internal.os.StatsdConfigProto; +import com.android.internal.os.StatsdConfigProto.StatsdConfig; +import com.android.os.AtomsProto; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Tests for {@link TestDrive} + */ +public class ConfigurationTest { + + private StatsdConfigProto.AtomMatcher findAndRemoveAtomMatcherById( + List<StatsdConfigProto.AtomMatcher> atomMatchers, long id) { + int numMatches = 0; + StatsdConfigProto.AtomMatcher match = null; + for (StatsdConfigProto.AtomMatcher atomMatcher : atomMatchers) { + if (id == atomMatcher.getId()) { + ++numMatches; + match = atomMatcher; + } + } + if (numMatches == 1) { + atomMatchers.remove(match); + return match; + } + return null; // Too many, or not found + } + + private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration(); + + @Test + public void testOnePushed() { + final int atom = 90; + assertFalse(TestDrive.Configuration.isPulledAtom(atom)); + mConfiguration.addAtom(atom); + StatsdConfig config = mConfiguration.createConfig(); + + //event_metric { + // id: 1111 + // what: 1234567 + //} + //atom_matcher { + // id: 1234567 + // simple_atom_matcher { + // atom_id: 90 + // } + //} + + assertEquals(1, config.getEventMetricCount()); + assertEquals(0, config.getGaugeMetricCount()); + + assertTrue(mConfiguration.isTrackedMetric(config.getEventMetric(0).getId())); + + final List<StatsdConfigProto.AtomMatcher> atomMatchers = + new ArrayList<>(config.getAtomMatcherList()); + assertEquals(atom, + findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat()) + .getSimpleAtomMatcher().getAtomId()); + assertEquals(0, atomMatchers.size()); + } + + @Test + public void testOnePulled() { + final int atom = 10022; + assertTrue(TestDrive.Configuration.isPulledAtom(atom)); + mConfiguration.addAtom(atom); + StatsdConfig config = mConfiguration.createConfig(); + + //gauge_metric { + // id: 1111 + // what: 1234567 + // gauge_fields_filter { + // include_all: true + // } + // bucket: ONE_MINUTE + // sampling_type: FIRST_N_SAMPLES + // max_num_gauge_atoms_per_bucket: 100 + // trigger_event: 1111111 + //} + //atom_matcher { + // id: 1111111 + // simple_atom_matcher { + // atom_id: 47 + // } + //} + //atom_matcher { + // id: 1234567 + // simple_atom_matcher { + // atom_id: 10022 + // } + //} + + assertEquals(0, config.getEventMetricCount()); + assertEquals(1, config.getGaugeMetricCount()); + + assertTrue(mConfiguration.isTrackedMetric(config.getGaugeMetric(0).getId())); + + final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0); + assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll()); + + final List<StatsdConfigProto.AtomMatcher> atomMatchers = + new ArrayList<>(config.getAtomMatcherList()); + assertEquals(atom, + findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat()) + .getSimpleAtomMatcher().getAtomId()); + assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER, + findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent()) + .getSimpleAtomMatcher().getAtomId()); + assertEquals(0, atomMatchers.size()); + } + + @Test + public void testOnePulledTwoPushed() { + final int pulledAtom = 10022; + assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom)); + mConfiguration.addAtom(pulledAtom); + + Integer[] pushedAtoms = new Integer[]{244, 245}; + for (int atom : pushedAtoms) { + assertFalse(TestDrive.Configuration.isPulledAtom(atom)); + mConfiguration.addAtom(atom); + } + StatsdConfig config = mConfiguration.createConfig(); + + // event_metric { + // id: 1111 + // what: 1234567 + // } + // event_metric { + // id: 1112 + // what: 1234568 + // } + // gauge_metric { + // id: 1114 + // what: 1234570 + // gauge_fields_filter { + // include_all: true + // } + // bucket: ONE_MINUTE + // sampling_type: FIRST_N_SAMPLES + // max_num_gauge_atoms_per_bucket: 100 + // trigger_event: 1111111 + // } + // atom_matcher { + // id: 1111111 + // simple_atom_matcher { + // atom_id: 47 + // } + // } + // atom_matcher { + // id: 1234567 + // simple_atom_matcher { + // atom_id: 244 + // } + // } + // atom_matcher { + // id: 1234568 + // simple_atom_matcher { + // atom_id: 245 + // } + // } + // atom_matcher { + // id: 1234570 + // simple_atom_matcher { + // atom_id: 10022 + // } + // } + + assertEquals(2, config.getEventMetricCount()); + assertEquals(1, config.getGaugeMetricCount()); + + final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0); + assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId())); + assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll()); + for (StatsdConfigProto.EventMetric eventMetric : config.getEventMetricList()) { + assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId())); + } + + final List<StatsdConfigProto.AtomMatcher> atomMatchers = + new ArrayList<>(config.getAtomMatcherList()); + + assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat()) + .getSimpleAtomMatcher().getAtomId()); + assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER, + findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent()) + .getSimpleAtomMatcher().getAtomId()); + + Integer[] actualAtoms = new Integer[]{ + findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat()) + .getSimpleAtomMatcher().getAtomId(), + findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(1).getWhat()) + .getSimpleAtomMatcher().getAtomId()}; + Arrays.sort(actualAtoms); + assertArrayEquals(pushedAtoms, actualAtoms); + + assertEquals(0, atomMatchers.size()); + } + + @Test + public void testOnePulledTwoPushedTogether() { + mConfiguration.mOnePushedAtomEvent = true; // Use one event grabbing all pushed atoms + + final int pulledAtom = 10022; + assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom)); + mConfiguration.addAtom(pulledAtom); + + Integer[] pushedAtoms = new Integer[]{244, 245}; + for (int atom : pushedAtoms) { + assertFalse(TestDrive.Configuration.isPulledAtom(atom)); + mConfiguration.addAtom(atom); + } + StatsdConfig config = mConfiguration.createConfig(); + + // event_metric { + // id: 1112 + // what: 1234570 + // } + // gauge_metric { + // id: 1111 + // what: 1234567 + // gauge_fields_filter { + // include_all: true + // } + // bucket: ONE_MINUTE + // sampling_type: FIRST_N_SAMPLES + // max_num_gauge_atoms_per_bucket: 100 + // trigger_event: 1111111 + // } + // atom_matcher { + // id: 1111111 + // simple_atom_matcher { + // atom_id: 47 + // } + // } + // atom_matcher { + // id: 1234567 + // simple_atom_matcher { + // atom_id: 10022 + // } + // } + // atom_matcher { + // id: 1234568 + // simple_atom_matcher { + // atom_id: 244 + // } + // } + // atom_matcher { + // id: 1234569 + // simple_atom_matcher { + // atom_id: 245 + // } + // } + // atom_matcher { + // id: 1234570 + // combination { + // operation: OR + // matcher: 1234568 + // matcher: 1234569 + // } + // } + + assertEquals(1, config.getEventMetricCount()); + assertEquals(1, config.getGaugeMetricCount()); + + final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0); + assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId())); + assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll()); + + StatsdConfigProto.EventMetric eventMetric = config.getEventMetric(0); + assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId())); + + final List<StatsdConfigProto.AtomMatcher> atomMatchers = + new ArrayList<>(config.getAtomMatcherList()); + + assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat()) + .getSimpleAtomMatcher().getAtomId()); + assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER, + findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent()) + .getSimpleAtomMatcher().getAtomId()); + + StatsdConfigProto.AtomMatcher unionMatcher = findAndRemoveAtomMatcherById(atomMatchers, + eventMetric.getWhat()); + assertNotNull(unionMatcher.getCombination()); + assertEquals(2, unionMatcher.getCombination().getMatcherCount()); + + Integer[] actualAtoms = new Integer[]{ + findAndRemoveAtomMatcherById(atomMatchers, + unionMatcher.getCombination().getMatcher(0)) + .getSimpleAtomMatcher().getAtomId(), + findAndRemoveAtomMatcherById(atomMatchers, + unionMatcher.getCombination().getMatcher(1)) + .getSimpleAtomMatcher().getAtomId()}; + Arrays.sort(actualAtoms); + assertArrayEquals(pushedAtoms, actualAtoms); + + assertEquals(0, atomMatchers.size()); + } +} diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java new file mode 100644 index 000000000000..363fac0c78ba --- /dev/null +++ b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.statsd.shelltools.testdrive; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * Tests for {@link TestDrive} + */ +@RunWith(Parameterized.class) +public class TestDriveTest { + /** + * Expected results of a single iteration of the paramerized test. + */ + static class Expect { + public boolean success; + public Integer[] atoms; + public boolean onePushedAtomEvent = false; + public String extraPackage = null; + public String target; + public boolean terse = false; + + static Expect success(Integer... atoms) { + return new Expect(true, atoms, + TARGET); + } + Expect(boolean success, Integer[] atoms, String target) { + this.success = success; + this.atoms = atoms; + this.target = target; + } + static final Expect FAILURE = new Expect(false, null, null); + Expect onePushedAtomEvent() { + this.onePushedAtomEvent = true; + return this; + } + Expect extraPackage() { + this.extraPackage = TestDriveTest.PACKAGE; + return this; + } + Expect terse() { + this.terse = true; + return this; + } + } + + @Parameterized.Parameter(0) + public String[] mArgs; + + @Parameterized.Parameter(1) + public List<String> mConnectedDevices; + + @Parameterized.Parameter(2) + public String mDefaultDevice; + + @Parameterized.Parameter(3) + public Expect mExpect; + + private static final String TARGET = "target"; + private static final List<String> TARGET_AND_OTHER = Arrays.asList("otherDevice", + TARGET); + private static final List<String> TWO_OTHER_DEVICES = Arrays.asList( + "other1", "other2"); + private static final List<String> TARGET_ONLY = Collections.singletonList(TARGET); + private static final List<String> NOT_TARGET = Collections.singletonList("other"); + private static final List<String> NO_DEVICES = Collections.emptyList(); + private static final String PACKAGE = "extraPackage"; + + @Parameterized.Parameters + public static Collection<Object[]> data() { + return Arrays.asList( + new Object[]{new String[]{}, null, null, + Expect.FAILURE}, // Usage explanation + new Object[]{new String[]{"244", "245"}, null, null, + Expect.FAILURE}, // Failure looking up connected devices + new Object[]{new String[]{"244", "245"}, NO_DEVICES, null, + Expect.FAILURE}, // No connected devices + new Object[]{new String[]{"-s", TARGET, "244", "245"}, NOT_TARGET, null, + Expect.FAILURE}, // Wrong device connected + new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, null, + Expect.FAILURE}, // Wrong devices connected + new Object[]{new String[]{"244", "245"}, TARGET_ONLY, null, + Expect.success(244, 245)}, // If only one device connected, guess that one + new Object[]{new String[]{"244", "not_an_atom"}, TARGET_ONLY, null, + Expect.success(244)}, // Ignore non-atoms + new Object[]{new String[]{"not_an_atom"}, TARGET_ONLY, null, + Expect.FAILURE}, // Require at least one atom + new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, TARGET, + Expect.FAILURE}, // ANDROID_SERIAL specifies non-connected target + new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, TARGET, + Expect.success(244, 245)}, // ANDROID_SERIAL specifies a valid target + new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, null, + Expect.FAILURE}, // Two connected devices, no indication of which to use + new Object[]{new String[]{"-one", "244", "245"}, TARGET_ONLY, null, + Expect.success(244, 245).onePushedAtomEvent()}, + new Object[]{new String[]{"-terse", "-one", "244", "245"}, TARGET_ONLY, null, + Expect.success(244, 245).onePushedAtomEvent().terse()}, + new Object[]{new String[]{"-one", "-terse", "244", "245"}, TARGET_ONLY, null, + Expect.success(244, 245).onePushedAtomEvent().terse()}, + new Object[]{new String[]{"-p", PACKAGE, "244", "245"}, TARGET_ONLY, null, + Expect.success(244, 245).extraPackage()}, + new Object[]{new String[]{"-p", PACKAGE, "-one", "244", "245"}, TARGET_ONLY, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent()}, + new Object[]{new String[]{"-one", "-p", PACKAGE, "244", "245"}, TARGET_ONLY, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent()}, + new Object[]{new String[]{"-s", TARGET, "-one", "-p", PACKAGE, "244", "245"}, + TARGET_AND_OTHER, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent()}, + new Object[]{new String[]{"-one", "-s", TARGET, "-p", PACKAGE, "244", "245"}, + TARGET_AND_OTHER, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent()}, + new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "244", "245"}, + TARGET_AND_OTHER, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent()}, + new Object[]{new String[]{"-terse", "-one", "-p", PACKAGE, "-s", TARGET, + "244", "245"}, + TARGET_AND_OTHER, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()}, + new Object[]{new String[]{"-one", "-terse", "-p", PACKAGE, "-s", TARGET, + "244", "245"}, + TARGET_AND_OTHER, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()}, + new Object[]{new String[]{"-one", "-p", PACKAGE, "-terse", "-s", TARGET, + "244", "245"}, + TARGET_AND_OTHER, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()}, + new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "-terse", + "244", "245"}, + TARGET_AND_OTHER, null, + Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()} + ); + } + + private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration(); + private final TestDrive mTestDrive = new TestDrive(); + + private static Integer[] collectAtoms(TestDrive.Configuration configuration) { + Integer[] result = new Integer[configuration.mPulledAtoms.size() + + configuration.mPushedAtoms.size()]; + int result_index = 0; + for (Integer atom : configuration.mPushedAtoms) { + result[result_index++] = atom; + } + for (Integer atom : configuration.mPulledAtoms) { + result[result_index++] = atom; + } + Arrays.sort(result); + return result; + } + + @Test + public void testProcessArgs() { + boolean result = mTestDrive.processArgs(mConfiguration, mArgs, mConnectedDevices, + mDefaultDevice); + if (mExpect.success) { + assertTrue(result); + assertArrayEquals(mExpect.atoms, collectAtoms(mConfiguration)); + assertEquals(mExpect.onePushedAtomEvent, mConfiguration.mOnePushedAtomEvent); + assertEquals(mExpect.target, mTestDrive.mDeviceSerial); + if (mExpect.terse) { + assertEquals(TestDrive.TerseDumper.class, mTestDrive.mDumper.getClass()); + } else { + assertEquals(TestDrive.BasicDumper.class, mTestDrive.mDumper.getClass()); + } + } else { + assertFalse(result); + } + } +} diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index 5f45d6932293..95778b5b3648 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -19208,6 +19208,8 @@ HSPLandroid/telephony/PreciseDataConnectionState;->toString()Ljava/lang/String; HSPLandroid/telephony/PreciseDataConnectionState;->writeToParcel(Landroid/os/Parcel;I)V HSPLandroid/telephony/Rlog;->d(Ljava/lang/String;Ljava/lang/String;)I HSPLandroid/telephony/ServiceState;->createLocationInfoSanitizedCopy(Z)Landroid/telephony/ServiceState; +HSPLandroid/telephony/ServiceState;->fillInNotifierBundle(Landroid/os/Bundle;)V +HSPLandroid/telephony/ServiceState;->newFromBundle(Landroid/os/Bundle;)Landroid/telephony/ServiceState; PLandroid/telephony/SignalStrength;-><init>(Landroid/telephony/SignalStrength;)V HPLandroid/telephony/SignalStrength;->copyFrom(Landroid/telephony/SignalStrength;)V HSPLandroid/telephony/SignalStrength;->isGsm()Z diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 18e5c3d2d7cc..77b3c81dee85 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -501,6 +501,18 @@ public abstract class AccessibilityService extends Service { */ public static final int GLOBAL_ACTION_KEYCODE_HEADSETHOOK = 10; + /** + * Action to trigger the Accessibility Button + * @hide + */ + public static final int GLOBAL_ACTION_ACCESSIBILITY_BUTTON = 11; + + /** + * Action to bring up the Accessibility Button's chooser menu + * @hide + */ + public static final int GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER = 12; + private static final String LOG_TAG = "AccessibilityService"; /** diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 6480a6abeb78..e0ae750ba5ee 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6549,8 +6549,12 @@ public class Activity extends ContextThemeWrapper * {@link #RESULT_CANCELED} if the activity explicitly returned that, * didn't return any result, or crashed during its operation. * - * <p>You will receive this call immediately before onResume() when your - * activity is re-starting. + * <p>An activity can never receive a result in the resumed state. You can count on + * {@link #onResume} being called after this method, though not necessarily immediately after. + * If the activity was resumed, it will be paused and the result will be delivered, followed + * by {@link #onResume}. If the activity wasn't in the resumed state, then the result will + * be delivered, with {@link #onResume} called sometime later when the activity becomes active + * again. * * <p>This method is never invoked if your activity sets * {@link android.R.styleable#AndroidManifestActivity_noHistory noHistory} to diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index bea85a9974d9..e19d5ecdd7d2 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1170,6 +1170,8 @@ public final class ActivityThread extends ClientTransactionHandler { } catch (IOException e) { Slog.e(TAG, "Failed to duplicate heap dump file descriptor", e); return; + } finally { + IoUtils.closeQuietly(fd); } dhd.finishCallback = finishCallback; sendMessage(H.DUMP_HEAP, dhd, 0, 0, true /*async*/); @@ -3085,6 +3087,11 @@ public final class ActivityThread extends ClientTransactionHandler { return mActivities.get(token); } + @VisibleForTesting(visibility = PACKAGE) + public Configuration getConfiguration() { + return mConfiguration; + } + @Override public void updatePendingConfiguration(Configuration config) { synchronized (mResourcesManager) { diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index 00627ef381ab..ae8a2cbf5120 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -31,7 +31,6 @@ import android.os.Parcelable; import android.os.RemoteException; import android.os.WorkSource; import android.text.TextUtils; -import android.util.ArrayMap; import android.util.Log; import android.util.proto.ProtoOutputStream; @@ -40,6 +39,8 @@ import libcore.timezone.ZoneInfoDb; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; /** * This class provides access to the system alarm services. These allow you @@ -222,26 +223,12 @@ public class AlarmManager { } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } - - synchronized (AlarmManager.class) { - if (sWrappers != null) { - sWrappers.remove(mListener); - } - } } @Override public void doAlarm(IAlarmCompleteListener alarmManager) { mCompletion = alarmManager; - // Remove this listener from the wrapper cache first; the server side - // already considers it gone - synchronized (AlarmManager.class) { - if (sWrappers != null) { - sWrappers.remove(mListener); - } - } - mHandler.post(this); } @@ -263,9 +250,14 @@ public class AlarmManager { } } - // Tracking of the OnAlarmListener -> wrapper mapping, for cancel() support. - // Access is synchronized on the AlarmManager class object. - private static ArrayMap<OnAlarmListener, ListenerWrapper> sWrappers; + /** + * Tracking of the OnAlarmListener -> ListenerWrapper mapping, for cancel() support. + * An entry is guaranteed to stay in this map as long as its ListenerWrapper is held by the + * server. + * + * <p>Access is synchronized on the AlarmManager class object. + */ + private static WeakHashMap<OnAlarmListener, WeakReference<ListenerWrapper>> sWrappers; /** * package private on purpose @@ -682,14 +674,17 @@ public class AlarmManager { if (listener != null) { synchronized (AlarmManager.class) { if (sWrappers == null) { - sWrappers = new ArrayMap<OnAlarmListener, ListenerWrapper>(); + sWrappers = new WeakHashMap<>(); } - recipientWrapper = sWrappers.get(listener); + final WeakReference<ListenerWrapper> weakRef = sWrappers.get(listener); + if (weakRef != null) { + recipientWrapper = weakRef.get(); + } // no existing wrapper => build a new one if (recipientWrapper == null) { recipientWrapper = new ListenerWrapper(listener); - sWrappers.put(listener, recipientWrapper); + sWrappers.put(listener, new WeakReference<>(recipientWrapper)); } } @@ -948,7 +943,10 @@ public class AlarmManager { ListenerWrapper wrapper = null; synchronized (AlarmManager.class) { if (sWrappers != null) { - wrapper = sWrappers.get(listener); + final WeakReference<ListenerWrapper> weakRef = sWrappers.get(listener); + if (weakRef != null) { + wrapper = weakRef.get(); + } } } diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 37f683ef435f..33bacf0d1146 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1083,7 +1083,7 @@ public class AppOpsManager { * @hide */ public static final int OP_ACTIVATE_PLATFORM_VPN = AppProtoEnums.APP_OP_ACTIVATE_PLATFORM_VPN; - /** @hide */ + /** @hide Controls whether or not read logs are available for incremental installations. */ public static final int OP_LOADER_USAGE_STATS = AppProtoEnums.APP_OP_LOADER_USAGE_STATS; // App op deprecated/removed. diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index bb64c3492c4f..a4256a9d8ab3 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -250,6 +250,10 @@ class ContextImpl extends Context { private final Object mSync = new Object(); + /** + * Whether this is created from {@link #createSystemContext(ActivityThread)} or + * {@link #createSystemUiContext(ContextImpl, int)} or any {@link Context} that system UI uses. + */ private boolean mIsSystemOrSystemUiContext; private boolean mIsUiContext; private boolean mIsAssociatedWithDisplay; @@ -1922,16 +1926,18 @@ class ContextImpl extends Context { /** @hide */ @Override public boolean isUiContext() { - return mIsSystemOrSystemUiContext || mIsUiContext || isSystemOrSystemUI(); + return mIsSystemOrSystemUiContext || mIsUiContext; } /** * Temporary workaround to permit incorrect usages of Context by SystemUI. - * TODO(b/149790106): Fix usages and remove. + * TODO(b/147647877): Fix usages and remove. */ - private boolean isSystemOrSystemUI() { - return ActivityThread.isSystem() || checkPermission("android.permission.STATUS_BAR_SERVICE", - Binder.getCallingPid(), Binder.getCallingUid()) == PERMISSION_GRANTED; + private static boolean isSystemOrSystemUI(Context context) { + return ActivityThread.isSystem() || context.checkPermission( + "android.permission.STATUS_BAR_SERVICE", + Binder.getCallingPid(), + Binder.getCallingUid()) == PERMISSION_GRANTED; } private static boolean isUiComponent(String name) { @@ -2467,7 +2473,7 @@ class ContextImpl extends Context { @Override public Display getDisplay() { - if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay && !isSystemOrSystemUI()) { + if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay) { throw new UnsupportedOperationException("Tried to obtain display from a Context not " + "associated with one. Only visual Contexts (such as Activity or one created " + "with Context#createWindowContext) or ones created with " @@ -2643,6 +2649,7 @@ class ContextImpl extends Context { ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null, 0, null, opPackageName); context.setResources(packageInfo.getResources()); + context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context); return context; } @@ -2672,6 +2679,7 @@ class ContextImpl extends Context { activityInfo.splitName, activityToken, null, 0, classLoader, null); context.mIsUiContext = true; context.mIsAssociatedWithDisplay = true; + context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context); // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY. displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY; diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl index 145d5139cdc2..1a619bd4475a 100644 --- a/core/java/android/app/ITaskStackListener.aidl +++ b/core/java/android/app/ITaskStackListener.aidl @@ -43,9 +43,10 @@ oneway interface ITaskStackListener { * @param homeVisible whether or not the home task is visible * @param clearedTask whether or not the launch activity also cleared the task as a part of * starting + * @param wasVisible whether the activity was visible before the restart attempt */ void onActivityRestartAttempt(in ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask); + boolean clearedTask, boolean wasVisible); /** * Called when we launched an activity that we forced to be resizable. diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index af027837ec91..f26b136da3a8 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3071,8 +3071,8 @@ public class Notification implements Parcelable StringBuilder sb = new StringBuilder(); sb.append("Notification(channel="); sb.append(getChannelId()); - sb.append(" pri="); - sb.append(priority); + sb.append(" shortcut="); + sb.append(getShortcutId()); sb.append(" contentView="); if (contentView != null) { sb.append(contentView.getPackage()); diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index 9f8d3c4090d6..cf2f7690bc2c 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -161,6 +161,19 @@ public final class NotificationChannel implements Parcelable { USER_LOCKED_ALLOW_BUBBLE }; + /** + * @hide + */ + public static final int DEFAULT_ALLOW_BUBBLE = -1; + /** + * @hide + */ + public static final int ALLOW_BUBBLE_ON = 1; + /** + * @hide + */ + public static final int ALLOW_BUBBLE_OFF = 0; + private static final int DEFAULT_LIGHT_COLOR = 0; private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE; @@ -168,12 +181,6 @@ public final class NotificationChannel implements Parcelable { NotificationManager.IMPORTANCE_UNSPECIFIED; private static final boolean DEFAULT_DELETED = false; private static final boolean DEFAULT_SHOW_BADGE = true; - /** - * @hide - */ - public static final int DEFAULT_ALLOW_BUBBLE = -1; - private static final int ALLOW_BUBBLE_ON = 1; - private static final int ALLOW_BUBBLE_OFF = 0; @UnsupportedAppUsage private String mId; diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java index 93772de0ba30..bfa91aabc6f5 100644 --- a/core/java/android/app/TaskStackListener.java +++ b/core/java/android/app/TaskStackListener.java @@ -55,7 +55,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { @Override @UnsupportedAppUsage public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask) throws RemoteException { + boolean clearedTask, boolean wasVisible) throws RemoteException { } @Override diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 41e2dc0de4d6..8073982ef745 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -10251,6 +10251,9 @@ public class DevicePolicyManager { * <p> * The confirm credentials screen can be created using * {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent}. + * <p> + * Starting from Android R, the organization color will no longer be used as the background + * color of the confirm credentials screen. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param color The 24bit (0xRRGGBB) representation of the color to be used. @@ -10953,6 +10956,22 @@ public class DevicePolicyManager { } /** + * Returns whether factory reset protection policy is supported on the device. + * + * @return {@code true} if the device support factory reset protection policy. + * + * @hide + */ + @TestApi + public boolean isFactoryResetProtectionPolicySupported() { + try { + return mService.isFactoryResetProtectionPolicySupported(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** * Called by the device owner or profile owner to clear application user data of a given * package. The behaviour of this is equivalent to the target application calling * {@link android.app.ActivityManager#clearApplicationUserData()}. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index d10153c11723..9c6a274ccf8c 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -108,6 +108,7 @@ interface IDevicePolicyManager { void setFactoryResetProtectionPolicy(in ComponentName who, in FactoryResetProtectionPolicy policy); FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(in ComponentName who); + boolean isFactoryResetProtectionPolicySupported(); ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList); ComponentName getGlobalProxyAdmin(int userHandle); diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java index 16ddbc147d82..96a4debd3d6a 100644 --- a/core/java/android/app/role/RoleControllerManager.java +++ b/core/java/android/app/role/RoleControllerManager.java @@ -21,6 +21,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemService; +import android.annotation.TestApi; import android.app.ActivityThread; import android.content.ComponentName; import android.content.Context; @@ -48,6 +49,7 @@ import java.util.function.Consumer; * @hide */ @SystemService(Context.ROLE_CONTROLLER_SERVICE) +@TestApi public class RoleControllerManager { private static final String LOG_TAG = RoleControllerManager.class.getSimpleName(); @@ -73,6 +75,8 @@ public class RoleControllerManager { * PackageManagerService lock in constructor. * * @see #createWithInitializedRemoteServiceComponentName(Handler, Context) + * + * @hide */ public static void initializeRemoteServiceComponentName(@NonNull Context context) { sRemoteServiceComponentName = getRemoteServiceComponentName(context); @@ -83,6 +87,8 @@ public class RoleControllerManager { * name so that we can avoid acquiring the PackageManagerService lock in constructor. * * @see #initializeRemoteServiceComponentName(Context) + * + * @hide */ @NonNull public static RoleControllerManager createWithInitializedRemoteServiceComponentName( @@ -113,6 +119,9 @@ public class RoleControllerManager { } } + /** + * @hide + */ public RoleControllerManager(@NonNull Context context) { this(getRemoteServiceComponentName(context), context.getMainThreadHandler(), context); } @@ -128,6 +137,8 @@ public class RoleControllerManager { /** * @see RoleControllerService#onGrantDefaultRoles() + * + * @hide */ public void grantDefaultRoles(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { @@ -141,6 +152,8 @@ public class RoleControllerManager { /** * @see RoleControllerService#onAddRoleHolder(String, String, int) + * + * @hide */ public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { @@ -155,6 +168,8 @@ public class RoleControllerManager { /** * @see RoleControllerService#onRemoveRoleHolder(String, String, int) + * + * @hide */ public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { @@ -169,6 +184,8 @@ public class RoleControllerManager { /** * @see RoleControllerService#onClearRoleHolders(String, int) + * + * @hide */ public void onClearRoleHolders(@NonNull String roleName, @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { @@ -186,6 +203,8 @@ public class RoleControllerManager { * * @deprecated Use {@link #isApplicationVisibleForRole(String, String, Executor, Consumer)} * instead. + * + * @hide */ @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) public void isApplicationQualifiedForRole(@NonNull String roleName, @NonNull String packageName, @@ -201,8 +220,11 @@ public class RoleControllerManager { /** * @see RoleControllerService#onIsApplicationVisibleForRole(String, String) + * + * @hide */ @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) + @TestApi public void isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { @@ -216,8 +238,11 @@ public class RoleControllerManager { /** * @see RoleControllerService#onIsRoleVisible(String) + * + * @hide */ @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) + @TestApi public void isRoleVisible(@NonNull String roleName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java index 1923bf3c5a23..234216539e97 100644 --- a/core/java/android/content/ClipData.java +++ b/core/java/android/content/ClipData.java @@ -27,7 +27,6 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Parcel; -import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.StrictMode; import android.text.Html; @@ -171,11 +170,6 @@ public class ClipData implements Parcelable { static final String[] MIMETYPES_TEXT_INTENT = new String[] { ClipDescription.MIMETYPE_TEXT_INTENT }; - // Constants used in {@link #writeHtmlTextToParcel}. - static final int PARCEL_MAX_SIZE_BYTES = 800 * 1024; - static final int PARCEL_TYPE_STRING = 0; - static final int PARCEL_TYPE_PFD = 1; - final ClipDescription mClipDescription; final Bitmap mIcon; @@ -231,8 +225,7 @@ public class ClipData implements Parcelable { * with an alternative HTML formatted representation. You <em>must</em> * supply a plain text representation in addition to HTML text; coercion * will not be done from HTML formatted text into plain text. - * <p class="note"><strong>Note:</strong> It is strongly recommended to - * use content: URI for sharing large clip data. Starting on API 30, + * <p><strong>Warning:</strong> Use content: URI for sharing large clip data. * ClipData.Item doesn't accept an HTML text if it's larger than 800KB. * </p> */ @@ -1135,7 +1128,7 @@ public class ClipData implements Parcelable { for (int i=0; i<N; i++) { Item item = mItems.get(i); TextUtils.writeToParcel(item.mText, dest, flags); - writeHtmlTextToParcel(item.mHtmlText, dest, flags); + dest.writeString8(item.mHtmlText); if (item.mIntent != null) { dest.writeInt(1); item.mIntent.writeToParcel(dest, flags); @@ -1162,7 +1155,7 @@ public class ClipData implements Parcelable { final int N = in.readInt(); for (int i=0; i<N; i++) { CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); - String htmlText = readHtmlTextFromParcel(in); + String htmlText = in.readString8(); Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null; Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null; mItems.add(new Item(text, htmlText, intent, uri)); @@ -1182,61 +1175,4 @@ public class ClipData implements Parcelable { return new ClipData[size]; } }; - - /** - * Helper function for writing an HTML text into a parcel. - * If the text size is larger than 400KB, it writes the text to a file descriptor to prevent the - * parcel from exceeding 800KB binder size limit. {@link android.os.Binder#checkParcel()} - * Otherwise, it directly writes the text into the parcel. - * Note: This function is a workaround for existing applications that still use HTML for sharing - * large clip data. We will ask application developers to use content: URI instead and remove - * this function in API 30. - */ - private static void writeHtmlTextToParcel(String text, Parcel dest, int flags) { - byte[] textData = (text != null) ? text.getBytes() : new byte[0]; - if (textData.length > PARCEL_MAX_SIZE_BYTES / 2 - && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { - try { - ParcelFileDescriptor pfd = ParcelFileDescriptor.fromData(textData, null); - dest.writeInt(PARCEL_TYPE_PFD); - dest.writeParcelable(pfd, flags); - } catch (IOException e) { - throw new IllegalStateException( - "Error creating the shared memory area: " + e.toString()); - } - } else { - dest.writeInt(PARCEL_TYPE_STRING); - dest.writeString8(text); - } - } - - /** - * Reads a text written by writeHtmlTextToParcel. - */ - private static String readHtmlTextFromParcel(Parcel in) { - if (in.readInt() == PARCEL_TYPE_STRING) { - return in.readString8(); - } - ParcelFileDescriptor pfd = - in.readParcelable(ParcelFileDescriptor.class.getClassLoader()); - if (pfd == null) { - throw new IllegalStateException("Error reading ParcelFileDescriptor from Parcel"); - } - FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); - InputStreamReader reader = new InputStreamReader(fis); - StringBuilder builder = new StringBuilder(); - char[] buffer = new char[4096]; - int numRead; - try { - while ((numRead = reader.read(buffer)) != -1) { - builder.append(buffer, 0, numRead); - } - return builder.toString(); - } catch (IOException e) { - throw new IllegalStateException( - "Error reading data from ParcelFileDescriptor: " + e.toString()); - } finally { - IoUtils.closeQuietly(fis); - } - } } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index b37521b1189b..043953d1aabd 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -25,7 +25,6 @@ import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ProcessInfo; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Build; @@ -39,8 +38,6 @@ import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.Parcelling; -import com.android.internal.util.Parcelling.BuiltIn.ForBoolean; import com.android.server.SystemConfig; import java.lang.annotation.Retention; @@ -1725,9 +1722,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString8(scanPublicSourceDir); dest.writeString8(sourceDir); dest.writeString8(publicSourceDir); - dest.writeStringArray(splitNames); - dest.writeStringArray(splitSourceDirs); - dest.writeStringArray(splitPublicSourceDirs); + dest.writeString8Array(splitNames); + dest.writeString8Array(splitSourceDirs); + dest.writeString8Array(splitPublicSourceDirs); dest.writeSparseArray((SparseArray) splitDependencies); dest.writeString8(nativeLibraryDir); dest.writeString8(secondaryNativeLibraryDir); @@ -1735,10 +1732,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(nativeLibraryRootRequiresIsa ? 1 : 0); dest.writeString8(primaryCpuAbi); dest.writeString8(secondaryCpuAbi); - dest.writeStringArray(resourceDirs); + dest.writeString8Array(resourceDirs); dest.writeString8(seInfo); dest.writeString8(seInfoUser); - dest.writeStringArray(sharedLibraryFiles); + dest.writeString8Array(sharedLibraryFiles); dest.writeTypedList(sharedLibraryInfos); dest.writeString8(dataDir); dest.writeString8(deviceProtectedDataDir); @@ -1760,7 +1757,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(category); dest.writeInt(targetSandboxVersion); dest.writeString8(classLoaderName); - dest.writeStringArray(splitClassLoaderNames); + dest.writeString8Array(splitClassLoaderNames); dest.writeInt(compileSdkVersion); dest.writeString8(compileSdkVersionCodename); dest.writeString8(appComponentFactory); @@ -1806,9 +1803,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { scanPublicSourceDir = source.readString8(); sourceDir = source.readString8(); publicSourceDir = source.readString8(); - splitNames = source.readStringArray(); - splitSourceDirs = source.readStringArray(); - splitPublicSourceDirs = source.readStringArray(); + splitNames = source.createString8Array(); + splitSourceDirs = source.createString8Array(); + splitPublicSourceDirs = source.createString8Array(); splitDependencies = source.readSparseArray(null); nativeLibraryDir = source.readString8(); secondaryNativeLibraryDir = source.readString8(); @@ -1816,10 +1813,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { nativeLibraryRootRequiresIsa = source.readInt() != 0; primaryCpuAbi = source.readString8(); secondaryCpuAbi = source.readString8(); - resourceDirs = source.readStringArray(); + resourceDirs = source.createString8Array(); seInfo = source.readString8(); seInfoUser = source.readString8(); - sharedLibraryFiles = source.readStringArray(); + sharedLibraryFiles = source.createString8Array(); sharedLibraryInfos = source.createTypedArrayList(SharedLibraryInfo.CREATOR); dataDir = source.readString8(); deviceProtectedDataDir = source.readString8(); @@ -1841,7 +1838,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { category = source.readInt(); targetSandboxVersion = source.readInt(); classLoaderName = source.readString8(); - splitClassLoaderNames = source.readStringArray(); + splitClassLoaderNames = source.createString8Array(); compileSdkVersion = source.readInt(); compileSdkVersionCodename = source.readString8(); appComponentFactory = source.readString8(); diff --git a/core/java/android/content/pm/IDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl index 24a62c5638ec..efb00a016da5 100644 --- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl +++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl @@ -40,11 +40,15 @@ oneway interface IDataLoaderStatusListener { /** Installation can't continue as DataLoader failed to stream necessary data. */ const int DATA_LOADER_IMAGE_NOT_READY = 6; + /** DataLoader instance can't run at the moment, but might recover later. + * It's up to system to decide if the app is still usable. */ + const int DATA_LOADER_UNAVAILABLE = 7; + /** DataLoader reports that this instance is invalid and can never be restored. * Warning: this is a terminal status that data loader should use carefully and * the system should almost never use - e.g. only if all recovery attempts * fail and all retry limits are exceeded. */ - const int DATA_LOADER_UNRECOVERABLE = 7; + const int DATA_LOADER_UNRECOVERABLE = 8; /** Data loader status callback */ void onStatusChanged(in int dataLoaderId, in int status); diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java index 745a6c1a0dff..bfbd4c60b291 100644 --- a/core/java/android/content/pm/InstrumentationInfo.java +++ b/core/java/android/content/pm/InstrumentationInfo.java @@ -161,9 +161,9 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable { dest.writeString8(targetProcesses); dest.writeString8(sourceDir); dest.writeString8(publicSourceDir); - dest.writeStringArray(splitNames); - dest.writeStringArray(splitSourceDirs); - dest.writeStringArray(splitPublicSourceDirs); + dest.writeString8Array(splitNames); + dest.writeString8Array(splitSourceDirs); + dest.writeString8Array(splitPublicSourceDirs); dest.writeSparseArray((SparseArray) splitDependencies); dest.writeString8(dataDir); dest.writeString8(deviceProtectedDataDir); @@ -193,9 +193,9 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable { targetProcesses = source.readString8(); sourceDir = source.readString8(); publicSourceDir = source.readString8(); - splitNames = source.readStringArray(); - splitSourceDirs = source.readStringArray(); - splitPublicSourceDirs = source.readStringArray(); + splitNames = source.createString8Array(); + splitSourceDirs = source.createString8Array(); + splitPublicSourceDirs = source.createString8Array(); splitDependencies = source.readSparseArray(null); dataDir = source.readString8(); deviceProtectedDataDir = source.readString8(); diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 87dc0a17f41c..bbcac56cf8af 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -507,7 +507,8 @@ public class LauncherApps { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been added or updated. - * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) + * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, + * Executor) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. @@ -525,7 +526,8 @@ public class LauncherApps { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been removed. - * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) + * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, + * Executor) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index bb56ef7fd3a0..d7abb68b96a5 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -442,7 +442,7 @@ public class PackageInfo implements Parcelable { // Allow ApplicationInfo to be squashed. final boolean prevAllowSquashing = dest.allowSquashing(); dest.writeString8(packageName); - dest.writeStringArray(splitNames); + dest.writeString8Array(splitNames); dest.writeInt(versionCode); dest.writeInt(versionCodeMajor); dest.writeString8(versionName); @@ -465,7 +465,7 @@ public class PackageInfo implements Parcelable { dest.writeTypedArray(providers, parcelableFlags); dest.writeTypedArray(instrumentation, parcelableFlags); dest.writeTypedArray(permissions, parcelableFlags); - dest.writeStringArray(requestedPermissions); + dest.writeString8Array(requestedPermissions); dest.writeIntArray(requestedPermissionsFlags); dest.writeTypedArray(signatures, parcelableFlags); dest.writeTypedArray(configPreferences, parcelableFlags); @@ -509,7 +509,7 @@ public class PackageInfo implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private PackageInfo(Parcel source) { packageName = source.readString8(); - splitNames = source.createStringArray(); + splitNames = source.createString8Array(); versionCode = source.readInt(); versionCodeMajor = source.readInt(); versionName = source.readString8(); @@ -530,7 +530,7 @@ public class PackageInfo implements Parcelable { providers = source.createTypedArray(ProviderInfo.CREATOR); instrumentation = source.createTypedArray(InstrumentationInfo.CREATOR); permissions = source.createTypedArray(PermissionInfo.CREATOR); - requestedPermissions = source.createStringArray(); + requestedPermissions = source.createString8Array(); requestedPermissionsFlags = source.createIntArray(); signatures = source.createTypedArray(Signature.CREATOR); configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 6a5e6ca289b3..5795cd24f4b1 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -180,6 +180,7 @@ public abstract class PackageManager { GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, + MATCH_APEX, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoFlags {} @@ -5951,9 +5952,9 @@ public abstract class PackageManager { /** * Return the label to use for this application. * - * @return Returns the label associated with this application, or null if - * it could not be found for any reason. - * @param info The application to get the label of. + * @return Returns a {@link CharSequence} containing the label associated with + * this application, or its name the item does not have a label. + * @param info The {@link ApplicationInfo} of the application to get the label of. */ @NonNull public abstract CharSequence getApplicationLabel(@NonNull ApplicationInfo info); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 8a57f826ad2e..addac9853f92 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -6016,7 +6016,7 @@ public class PackageParser { // the last entry in pastSigningCertificates is the current signer, ignore it for (int i = 0; i < pastSigningCertificates.length - 1; i++) { - if (pastSigningCertificates[i].equals(oldDetails.signatures[i])) { + if (pastSigningCertificates[i].equals(oldDetails.signatures[0])) { return true; } } diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index c6c288239d1f..5f6befdcbaef 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -618,8 +618,8 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { super.writeToParcel(dest, parcelableFlags); dest.writeInt(protectionLevel); dest.writeInt(flags); - dest.writeString(group); - dest.writeString(backgroundPermission); + dest.writeString8(group); + dest.writeString8(backgroundPermission); dest.writeInt(descriptionRes); dest.writeInt(requestRes); TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags); @@ -678,8 +678,8 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { super(source); protectionLevel = source.readInt(); flags = source.readInt(); - group = source.readString(); - backgroundPermission = source.readString(); + group = source.readString8(); + backgroundPermission = source.readString8(); descriptionRes = source.readInt(); requestRes = source.readInt(); nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java index 82b07f24a906..4f2bf65adfca 100644 --- a/core/java/android/content/pm/ResolveInfo.java +++ b/core/java/android/content/pm/ResolveInfo.java @@ -443,7 +443,7 @@ public class ResolveInfo implements Parcelable { dest.writeInt(labelRes); TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags); dest.writeInt(icon); - dest.writeString(resolvePackageName); + dest.writeString8(resolvePackageName); dest.writeInt(targetUserId); dest.writeInt(system ? 1 : 0); dest.writeInt(noResourceId ? 1 : 0); @@ -491,7 +491,7 @@ public class ResolveInfo implements Parcelable { nonLocalizedLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); icon = source.readInt(); - resolvePackageName = source.readString(); + resolvePackageName = source.readString8(); targetUserId = source.readInt(); system = source.readInt() != 0; noResourceId = source.readInt() != 0; diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index fe4b36fd9ae3..da2a3d885fc6 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -26,6 +26,7 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -111,10 +112,19 @@ public final class SharedLibraryInfo implements Parcelable { } private SharedLibraryInfo(Parcel parcel) { - this(parcel.readString(), parcel.readString(), parcel.readArrayList(null), - parcel.readString(), parcel.readLong(), - parcel.readInt(), parcel.readParcelable(null), parcel.readArrayList(null), - parcel.createTypedArrayList(SharedLibraryInfo.CREATOR)); + mPath = parcel.readString8(); + mPackageName = parcel.readString8(); + if (parcel.readInt() != 0) { + mCodePaths = Arrays.asList(parcel.createString8Array()); + } else { + mCodePaths = null; + } + mName = parcel.readString8(); + mVersion = parcel.readLong(); + mType = parcel.readInt(); + mDeclaringPackage = parcel.readParcelable(null); + mDependentPackages = parcel.readArrayList(null); + mDependencies = parcel.createTypedArrayList(SharedLibraryInfo.CREATOR); } /** @@ -296,10 +306,15 @@ public final class SharedLibraryInfo implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeString(mPath); - parcel.writeString(mPackageName); - parcel.writeList(mCodePaths); - parcel.writeString(mName); + parcel.writeString8(mPath); + parcel.writeString8(mPackageName); + if (mCodePaths != null) { + parcel.writeInt(1); + parcel.writeString8Array(mCodePaths.toArray(new String[mCodePaths.size()])); + } else { + parcel.writeInt(0); + } + parcel.writeString8(mName); parcel.writeLong(mVersion); parcel.writeInt(mType); parcel.writeParcelable(mDeclaringPackage, flags); diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java index 8d8776f1bc23..85bf11ceb723 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -1759,6 +1759,12 @@ public final class ShortcutInfo implements Parcelable { return isDeclaredInManifest() && isVisibleToPublisher(); } + /** @hide */ + public boolean isNonManifestVisible() { + return !isDeclaredInManifest() && isVisibleToPublisher() + && (isPinned() || isCached() || isDynamic()); + } + /** * Return if a shortcut is immutable, in which case it cannot be modified with any of * {@link ShortcutManager} APIs. @@ -2053,8 +2059,8 @@ public final class ShortcutInfo implements Parcelable { final ClassLoader cl = getClass().getClassLoader(); mUserId = source.readInt(); - mId = source.readString(); - mPackageName = source.readString(); + mId = source.readString8(); + mPackageName = source.readString8(); mActivity = source.readParcelable(cl); mFlags = source.readInt(); mIconResId = source.readInt(); @@ -2076,12 +2082,12 @@ public final class ShortcutInfo implements Parcelable { mIntentPersistableExtrases = source.readParcelableArray(cl, PersistableBundle.class); mRank = source.readInt(); mExtras = source.readParcelable(cl); - mBitmapPath = source.readString(); + mBitmapPath = source.readString8(); - mIconResName = source.readString(); - mTitleResName = source.readString(); - mTextResName = source.readString(); - mDisabledMessageResName = source.readString(); + mIconResName = source.readString8(); + mTitleResName = source.readString8(); + mTextResName = source.readString8(); + mDisabledMessageResName = source.readString8(); int N = source.readInt(); if (N == 0) { @@ -2089,20 +2095,20 @@ public final class ShortcutInfo implements Parcelable { } else { mCategories = new ArraySet<>(N); for (int i = 0; i < N; i++) { - mCategories.add(source.readString().intern()); + mCategories.add(source.readString8().intern()); } } mPersons = source.readParcelableArray(cl, Person.class); mLocusId = source.readParcelable(cl); - mIconUri = source.readString(); + mIconUri = source.readString8(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mUserId); - dest.writeString(mId); - dest.writeString(mPackageName); + dest.writeString8(mId); + dest.writeString8(mPackageName); dest.writeParcelable(mActivity, flags); dest.writeInt(mFlags); dest.writeInt(mIconResId); @@ -2127,18 +2133,18 @@ public final class ShortcutInfo implements Parcelable { dest.writeParcelableArray(mIntentPersistableExtrases, flags); dest.writeInt(mRank); dest.writeParcelable(mExtras, flags); - dest.writeString(mBitmapPath); + dest.writeString8(mBitmapPath); - dest.writeString(mIconResName); - dest.writeString(mTitleResName); - dest.writeString(mTextResName); - dest.writeString(mDisabledMessageResName); + dest.writeString8(mIconResName); + dest.writeString8(mTitleResName); + dest.writeString8(mTextResName); + dest.writeString8(mDisabledMessageResName); if (mCategories != null) { final int N = mCategories.size(); dest.writeInt(N); for (int i = 0; i < N; i++) { - dest.writeString(mCategories.valueAt(i)); + dest.writeString8(mCategories.valueAt(i)); } } else { dest.writeInt(0); @@ -2146,7 +2152,7 @@ public final class ShortcutInfo implements Parcelable { dest.writeParcelableArray(mPersons, flags); dest.writeParcelable(mLocusId, flags); - dest.writeString(mIconUri); + dest.writeString8(mIconUri); } public static final @android.annotation.NonNull Creator<ShortcutInfo> CREATOR = diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index f1506645d10c..aca5b458a2d6 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -457,14 +457,14 @@ public class UserInfo implements Parcelable { @Override public void writeToParcel(Parcel dest, int parcelableFlags) { dest.writeInt(id); - dest.writeString(name); - dest.writeString(iconPath); + dest.writeString8(name); + dest.writeString8(iconPath); dest.writeInt(flags); - dest.writeString(userType); + dest.writeString8(userType); dest.writeInt(serialNumber); dest.writeLong(creationTime); dest.writeLong(lastLoggedInTime); - dest.writeString(lastLoggedInFingerprint); + dest.writeString8(lastLoggedInFingerprint); dest.writeBoolean(partial); dest.writeBoolean(preCreated); dest.writeInt(profileGroupId); @@ -486,14 +486,14 @@ public class UserInfo implements Parcelable { private UserInfo(Parcel source) { id = source.readInt(); - name = source.readString(); - iconPath = source.readString(); + name = source.readString8(); + iconPath = source.readString8(); flags = source.readInt(); - userType = source.readString(); + userType = source.readString8(); serialNumber = source.readInt(); creationTime = source.readLong(); lastLoggedInTime = source.readLong(); - lastLoggedInFingerprint = source.readString(); + lastLoggedInFingerprint = source.readString8(); partial = source.readBoolean(); preCreated = source.readBoolean(); profileGroupId = source.readInt(); diff --git a/core/java/android/content/pm/VersionedPackage.java b/core/java/android/content/pm/VersionedPackage.java index 21df7ecef015..2987557a54b4 100644 --- a/core/java/android/content/pm/VersionedPackage.java +++ b/core/java/android/content/pm/VersionedPackage.java @@ -60,7 +60,7 @@ public final class VersionedPackage implements Parcelable { } private VersionedPackage(Parcel parcel) { - mPackageName = parcel.readString(); + mPackageName = parcel.readString8(); mVersionCode = parcel.readLong(); } @@ -116,7 +116,7 @@ public final class VersionedPackage implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeString(mPackageName); + parcel.writeString8(mPackageName); parcel.writeLong(mVersionCode); } diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 4e189796bc48..197ad7412a1f 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -346,12 +346,11 @@ public class ParsingPackageUtils { } final ParsingPackage pkg = result.getResult(); - if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.R - && assets.containsAllocatedTable()) { + if (assets.containsAllocatedTable()) { final ParseResult<?> deferResult = input.deferError( - "Targeting R+ (version" + Build.VERSION_CODES.R + " and above) requires the" - + " resources.arsc of installed APKs to be stored uncompressed and" - + " aligned on a 4-byte boundary", + "Targeting R+ (version " + Build.VERSION_CODES.R + " and above) requires" + + " the resources.arsc of installed APKs to be stored uncompressed" + + " and aligned on a 4-byte boundary", DeferredError.RESOURCES_ARSC_COMPRESSED); if (deferResult.isError()) { return input.error(INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED, diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java index 65a8e15ba340..6bc962b67576 100644 --- a/core/java/android/hardware/hdmi/HdmiControlManager.java +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java @@ -650,6 +650,68 @@ public final class HdmiControlManager { } /** + * Controls whether volume control commands via HDMI CEC are enabled. + * + * <p>When disabled: + * <ul> + * <li>the device will not send any HDMI CEC audio messages + * <li>received HDMI CEC audio messages are responded to with {@code <Feature Abort>} + * </ul> + * + * <p>Effects on different device types: + * <table> + * <tr><th>HDMI CEC device type</th><th>enabled</th><th>disabled</th></tr> + * <tr> + * <td>TV (type: 0)</td> + * <td>Per CEC specification.</td> + * <td>TV changes system volume. TV no longer reacts to incoming volume changes via + * {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio Status>} + * .</td> + * </tr> + * <tr> + * <td>Playback device (type: 4)</td> + * <td>Device sends volume commands to TV/Audio system via {@code <User Control + * Pressed>}</td><td>Device does not send volume commands via {@code <User Control + * Pressed>}.</td> + * </tr> + * <tr> + * <td>Audio device (type: 5)</td> + * <td>Full "System Audio Control" capabilities.</td> + * <td>Audio device no longer reacts to incoming {@code <User Control Pressed>} + * volume commands. Audio device no longer reports volume changes via {@code <Report + * Audio Status>}.</td> + * </tr> + * </table> + * + * <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged. + * + * @param isHdmiCecVolumeControlEnabled target state of HDMI CEC volume control. + * @see Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED + * @hide + */ + @RequiresPermission(android.Manifest.permission.HDMI_CEC) + public void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) { + try { + mService.setHdmiCecVolumeControlEnabled(isHdmiCecVolumeControlEnabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Returns whether volume changes via HDMI CEC are enabled. + * @hide + */ + @RequiresPermission(android.Manifest.permission.HDMI_CEC) + public boolean isHdmiCecVolumeControlEnabled() { + try { + return mService.isHdmiCecVolumeControlEnabled(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Gets whether the system is in system audio mode. * * @hide diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl index a8fed2b03cfc..3582a927ff46 100644 --- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl +++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl @@ -80,6 +80,8 @@ interface IHdmiControlService { void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data); void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener); void setStandbyMode(boolean isStandbyModeOn); + void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled); + boolean isHdmiCecVolumeControlEnabled(); void reportAudioStatus(int deviceType, int volume, int maxVolume, boolean isMute); void setSystemAudioModeOnForAudioOnlySource(); } diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java index d12142c0be79..4bed985489ef 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -1945,7 +1945,7 @@ public class SoundTrigger { Looper looper = handler != null ? handler.getLooper() : Looper.getMainLooper(); try { return new SoundTriggerModule(getService(), moduleId, listener, looper); - } catch (RemoteException e) { + } catch (Exception e) { Log.e(TAG, "", e); return null; } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 93ce88b767bc..d3464fde4b75 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -784,10 +784,19 @@ public class InputMethodService extends AbstractInputMethodService { } } - // TODO(b/137800469): Add detailed docs explaining the inline suggestions process. /** - * This method should be implemented by subclass which supports displaying autofill inline - * suggestion. + * Called when Autofill is requesting an {@link InlineSuggestionsRequest} from the IME. + * + * <p>The Autofill Framework will first request the IME to create and send an + * {@link InlineSuggestionsRequest} back. Once Autofill Framework receives a valid request and + * also receives valid inline suggestions, they will be returned via + * {@link #onInlineSuggestionsResponse(InlineSuggestionsResponse)}.</p> + * + * <p>IME Lifecycle - The request will wait to be created after inputStarted</p> + * + * <p>If the IME wants to support displaying inline suggestions, they must set + * supportsInlineSuggestions in its XML and implement this method to return a valid + * {@link InlineSuggestionsRequest}.</p> * * @param uiExtras the extras that contain the UI renderer related information * @return an {@link InlineSuggestionsRequest} to be sent to Autofill. diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index 8108cf08d5c3..e7bba69dbb84 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -775,17 +775,10 @@ public class TrafficStats { * @see android.content.pm.ApplicationInfo#uid */ public static long getUidTxBytes(int uid) { - // This isn't actually enforcing any security; it just returns the - // unsupported value. The real filtering is done at the kernel level. - final int callingUid = android.os.Process.myUid(); - if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { - try { - return getStatsService().getUidStats(uid, TYPE_TX_BYTES); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } else { - return UNSUPPORTED; + try { + return getStatsService().getUidStats(uid, TYPE_TX_BYTES); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -808,17 +801,10 @@ public class TrafficStats { * @see android.content.pm.ApplicationInfo#uid */ public static long getUidRxBytes(int uid) { - // This isn't actually enforcing any security; it just returns the - // unsupported value. The real filtering is done at the kernel level. - final int callingUid = android.os.Process.myUid(); - if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { - try { - return getStatsService().getUidStats(uid, TYPE_RX_BYTES); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } else { - return UNSUPPORTED; + try { + return getStatsService().getUidStats(uid, TYPE_RX_BYTES); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -841,17 +827,10 @@ public class TrafficStats { * @see android.content.pm.ApplicationInfo#uid */ public static long getUidTxPackets(int uid) { - // This isn't actually enforcing any security; it just returns the - // unsupported value. The real filtering is done at the kernel level. - final int callingUid = android.os.Process.myUid(); - if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { - try { - return getStatsService().getUidStats(uid, TYPE_TX_PACKETS); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } else { - return UNSUPPORTED; + try { + return getStatsService().getUidStats(uid, TYPE_TX_PACKETS); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -874,17 +853,10 @@ public class TrafficStats { * @see android.content.pm.ApplicationInfo#uid */ public static long getUidRxPackets(int uid) { - // This isn't actually enforcing any security; it just returns the - // unsupported value. The real filtering is done at the kernel level. - final int callingUid = android.os.Process.myUid(); - if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { - try { - return getStatsService().getUidStats(uid, TYPE_RX_PACKETS); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } else { - return UNSUPPORTED; + try { + return getStatsService().getUidStats(uid, TYPE_RX_PACKETS); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index c7355dd695f0..9e13f05129a2 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -975,6 +975,15 @@ public class Environment { } /** + * Returns the path for android-specific OBB data on the SD card. + * @hide + */ + public static File[] buildExternalStorageAndroidObbDirs() { + throwIfUserRequired(); + return sCurrentUser.buildExternalStorageAndroidObbDirs(); + } + + /** * Generates the raw path to an application's data * @hide */ diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 0bf387e6d0a6..ab4bb0b9f2cd 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -137,7 +137,7 @@ public final class LocaleList implements Parcelable { @Override public void writeToParcel(Parcel dest, int parcelableFlags) { - dest.writeString(mStringRepresentation); + dest.writeString8(mStringRepresentation); } /** @@ -239,7 +239,7 @@ public final class LocaleList implements Parcelable { = new Parcelable.Creator<LocaleList>() { @Override public LocaleList createFromParcel(Parcel source) { - return LocaleList.forLanguageTags(source.readString()); + return LocaleList.forLanguageTags(source.readString8()); } @Override diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 93f6607ff9d4..e5bab6fc9230 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -1396,24 +1396,39 @@ public final class Parcel { } public final void writeStringArray(@Nullable String[] val) { + writeString16Array(val); + } + + @Nullable + public final String[] createStringArray() { + return createString16Array(); + } + + public final void readStringArray(@NonNull String[] val) { + readString16Array(val); + } + + /** {@hide} */ + public final void writeString8Array(@Nullable String[] val) { if (val != null) { int N = val.length; writeInt(N); for (int i=0; i<N; i++) { - writeString(val[i]); + writeString8(val[i]); } } else { writeInt(-1); } } + /** {@hide} */ @Nullable - public final String[] createStringArray() { + public final String[] createString8Array() { int N = readInt(); if (N >= 0) { String[] val = new String[N]; for (int i=0; i<N; i++) { - val[i] = readString(); + val[i] = readString8(); } return val; } else { @@ -1421,11 +1436,52 @@ public final class Parcel { } } - public final void readStringArray(@NonNull String[] val) { + /** {@hide} */ + public final void readString8Array(@NonNull String[] val) { int N = readInt(); if (N == val.length) { for (int i=0; i<N; i++) { - val[i] = readString(); + val[i] = readString8(); + } + } else { + throw new RuntimeException("bad array lengths"); + } + } + + /** {@hide} */ + public final void writeString16Array(@Nullable String[] val) { + if (val != null) { + int N = val.length; + writeInt(N); + for (int i=0; i<N; i++) { + writeString16(val[i]); + } + } else { + writeInt(-1); + } + } + + /** {@hide} */ + @Nullable + public final String[] createString16Array() { + int N = readInt(); + if (N >= 0) { + String[] val = new String[N]; + for (int i=0; i<N; i++) { + val[i] = readString16(); + } + return val; + } else { + return null; + } + } + + /** {@hide} */ + public final void readString16Array(@NonNull String[] val) { + int N = readInt(); + if (N == val.length) { + for (int i=0; i<N; i++) { + val[i] = readString16(); } } else { throw new RuntimeException("bad array lengths"); @@ -2641,20 +2697,7 @@ public final class Parcel { @UnsupportedAppUsage @Nullable public final String[] readStringArray() { - String[] array = null; - - int length = readInt(); - if (length >= 0) - { - array = new String[length]; - - for (int i = 0 ; i < length ; i++) - { - array[i] = readString(); - } - } - - return array; + return createString16Array(); } /** diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java index de274c082c80..e907e2204b7b 100644 --- a/core/java/android/os/UpdateEngine.java +++ b/core/java/android/os/UpdateEngine.java @@ -614,9 +614,6 @@ public class UpdateEngine { * encountered. Device is corrupted, and future updates must not be applied. * The device cannot recover without flashing and factory resets. * </ul> - * - * @throws ServiceSpecificException if other transient errors has occurred. - * A reboot may or may not help resolving the issue. */ @WorkerThread @ErrorCode diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index e251f8072b1f..a63b82e44f06 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -149,18 +149,18 @@ public final class StorageVolume implements Parcelable { } private StorageVolume(Parcel in) { - mId = in.readString(); - mPath = new File(in.readString()); - mInternalPath = new File(in.readString()); - mDescription = in.readString(); + mId = in.readString8(); + mPath = new File(in.readString8()); + mInternalPath = new File(in.readString8()); + mDescription = in.readString8(); mPrimary = in.readInt() != 0; mRemovable = in.readInt() != 0; mEmulated = in.readInt() != 0; mAllowMassStorage = in.readInt() != 0; mMaxFileSize = in.readLong(); mOwner = in.readParcelable(null); - mFsUuid = in.readString(); - mState = in.readString(); + mFsUuid = in.readString8(); + mState = in.readString8(); } /** @@ -503,17 +503,17 @@ public final class StorageVolume implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeString(mId); - parcel.writeString(mPath.toString()); - parcel.writeString(mInternalPath.toString()); - parcel.writeString(mDescription); + parcel.writeString8(mId); + parcel.writeString8(mPath.toString()); + parcel.writeString8(mInternalPath.toString()); + parcel.writeString8(mDescription); parcel.writeInt(mPrimary ? 1 : 0); parcel.writeInt(mRemovable ? 1 : 0); parcel.writeInt(mEmulated ? 1 : 0); parcel.writeInt(mAllowMassStorage ? 1 : 0); parcel.writeLong(mMaxFileSize); parcel.writeParcelable(mOwner, flags); - parcel.writeString(mFsUuid); - parcel.writeString(mState); + parcel.writeString8(mFsUuid); + parcel.writeString8(mState); } } diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index fb9065568e9b..d7aaa4d6cbf9 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -181,22 +181,22 @@ public class VolumeInfo implements Parcelable { @UnsupportedAppUsage public VolumeInfo(Parcel parcel) { - id = parcel.readString(); + id = parcel.readString8(); type = parcel.readInt(); if (parcel.readInt() != 0) { disk = DiskInfo.CREATOR.createFromParcel(parcel); } else { disk = null; } - partGuid = parcel.readString(); + partGuid = parcel.readString8(); mountFlags = parcel.readInt(); mountUserId = parcel.readInt(); state = parcel.readInt(); - fsType = parcel.readString(); - fsUuid = parcel.readString(); - fsLabel = parcel.readString(); - path = parcel.readString(); - internalPath = parcel.readString(); + fsType = parcel.readString8(); + fsUuid = parcel.readString8(); + fsLabel = parcel.readString8(); + path = parcel.readString8(); + internalPath = parcel.readString8(); } @UnsupportedAppUsage @@ -553,7 +553,7 @@ public class VolumeInfo implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeString(id); + parcel.writeString8(id); parcel.writeInt(type); if (disk != null) { parcel.writeInt(1); @@ -561,14 +561,14 @@ public class VolumeInfo implements Parcelable { } else { parcel.writeInt(0); } - parcel.writeString(partGuid); + parcel.writeString8(partGuid); parcel.writeInt(mountFlags); parcel.writeInt(mountUserId); parcel.writeInt(state); - parcel.writeString(fsType); - parcel.writeString(fsUuid); - parcel.writeString(fsLabel); - parcel.writeString(path); - parcel.writeString(internalPath); + parcel.writeString8(fsType); + parcel.writeString8(fsUuid); + parcel.writeString8(fsLabel); + parcel.writeString8(path); + parcel.writeString8(internalPath); } } diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java index f08e3d25632b..ed429dd835c3 100644 --- a/core/java/android/permission/PermissionControllerManager.java +++ b/core/java/android/permission/PermissionControllerManager.java @@ -161,6 +161,7 @@ public final class PermissionControllerManager { * * @hide */ + @TestApi public interface OnCountPermissionAppsResultCallback { /** * The result for {@link #countPermissionApps(List, int, @@ -514,6 +515,7 @@ public final class PermissionControllerManager { * * @hide */ + @TestApi @RequiresPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermission(@NonNull String packageName, @NonNull String permissionName) { @@ -534,6 +536,7 @@ public final class PermissionControllerManager { * * @hide */ + @TestApi @RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS) public void countPermissionApps(@NonNull List<String> permissionNames, @CountPermissionAppsFlag int flags, diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md index e116dc6f37a1..2bf08e2ff2d4 100644 --- a/core/java/android/permission/Permissions.md +++ b/core/java/android/permission/Permissions.md @@ -728,7 +728,7 @@ platforms manifest using the `appop` protection level Almost always the protection level is app-op | something else, like [signature](#signature-permissions) (in the case above) or [privileged](#privileged-permissions). -#### Checking a app-op permission +#### Checking an app-op permission The `PermissionChecker` utility can check app-op permissions with the [same syntax as runtime permissions](#checking-a-runtime-permission). @@ -764,7 +764,7 @@ class PermissionChecker { } ``` -#### Granting a app-op permission +#### Granting an app-op permission The permission's grant state is only considered if the app-op's mode is `MODE_DEFAULT`. This allows to have default grants while still being overridden by the app-op. diff --git a/core/java/android/permission/TEST_MAPPING b/core/java/android/permission/TEST_MAPPING index ba9f36a31f2e..69113ef8f946 100644 --- a/core/java/android/permission/TEST_MAPPING +++ b/core/java/android/permission/TEST_MAPPING @@ -5,6 +5,9 @@ "options": [ { "include-filter": "android.permission.cts.PermissionControllerTest" + }, + { + "include-filter": "android.permission.cts.RuntimePermissionPresentationInfoTest" } ] } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ac1998a04016..b280c5d63cd7 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2020,8 +2020,7 @@ public final class Settings { * In some cases, a matching Activity may not exist, so ensure you * safeguard against this. * <p> - * Input: The Intent's data URI specifies the application package name - * to be shown, with the "package" scheme. That is "package:com.my.app". + * Input: Nothing. * <p> * Output: Nothing. */ @@ -9614,6 +9613,43 @@ public final class Settings { */ public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled"; + /** + * Controls whether volume control commands via HDMI CEC are enabled. (0 = false, 1 = + * true). + * + * <p>Effects on different device types: + * <table> + * <tr><th>HDMI CEC device type</th><th>0: disabled</th><th>1: enabled</th></tr> + * <tr> + * <td>TV (type: 0)</td> + * <td>Per CEC specification.</td> + * <td>TV changes system volume. TV no longer reacts to incoming volume changes + * via {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio + * Status>}.</td> + * </tr> + * <tr> + * <td>Playback device (type: 4)</td> + * <td>Device sends volume commands to TV/Audio system via {@code <User Control + * Pressed>}</td> + * <td>Device does not send volume commands via {@code <User Control Pressed>}.</td> + * </tr> + * <tr> + * <td>Audio device (type: 5)</td> + * <td>Full "System Audio Control" capabilities.</td> + * <td>Audio device no longer reacts to incoming {@code <User Control Pressed>} + * volume commands. Audio device no longer reports volume changes via {@code + * <Report Audio Status>}.</td> + * </tr> + * </table> + * + * <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged. + * + * @hide + * @see android.hardware.hdmi.HdmiControlManager#setHdmiCecVolumeControlEnabled(boolean) + */ + public static final String HDMI_CONTROL_VOLUME_CONTROL_ENABLED = + "hdmi_control_volume_control_enabled"; + /** * Whether HDMI System Audio Control feature is enabled. If enabled, TV will try to turn on * system audio mode if there's a connected CEC-enabled AV Receiver. Then audio stream will @@ -10701,13 +10737,33 @@ public final class Settings { * The associated value is a specially formatted string that describes the * size and density of simulated secondary display devices. * <p> - * Format: {width}x{height}/{dpi};... + * Format: + * <pre> + * [display1];[display2];... + * </pre> + * with each display specified as: + * <pre> + * [mode1]|[mode2]|...,[flag1],[flag2],... + * </pre> + * with each mode specified as: + * <pre> + * [width]x[height]/[densityDpi] + * </pre> + * Supported flags: + * <ul> + * <li><pre>secure</pre>: creates a secure display</li> + * <li><pre>own_content_only</pre>: only shows this display's own content</li> + * <li><pre>should_show_system_decorations</pre>: supports system decorations</li> + * </ul> * </p><p> * Example: * <ul> * <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li> - * <li><code>1920x1080/320;1280x720/213</code>: make two overlays, the first - * at 1080p and the second at 720p.</li> + * <li><code>1920x1080/320,secure;1280x720/213</code>: make two overlays, the first at + * 1080p and secure; the second at 720p.</li> + * <li><code>1920x1080/320|3840x2160/640</code>: make one overlay that is 1920x1080 at + * 213dpi by default, but can also be upscaled to 3840x2160 at 640dpi by the system if the + * display device allows.</li> * <li>If the value is empty, then no overlay display devices are created.</li> * </ul></p> * @@ -13793,16 +13849,6 @@ public final class Settings { "show_notification_channel_warnings"; /** - * When enabled, requires all notifications in the conversation section to be backed - * by a long-lived sharing shortcut - * - * The value 1 - require a shortcut, 0 - do not require a shortcut - * @hide - */ - public static final String REQUIRE_SHORTCUTS_FOR_CONVERSATIONS = - "require_shortcuts_for_conversations"; - - /** * Whether cell is enabled/disabled * @hide */ diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java index 8f858d547b1f..d94160c2b40c 100644 --- a/core/java/android/service/autofill/FillRequest.java +++ b/core/java/android/service/autofill/FillRequest.java @@ -127,10 +127,16 @@ public final class FillRequest implements Parcelable { private final @RequestFlags int mFlags; /** - * Gets the {@link android.view.inputmethod.InlineSuggestionsRequest} associated + * Gets the {@link InlineSuggestionsRequest} associated * with this request. * - * TODO(b/137800469): Add more doc describing how to handle the inline suggestions request. + * <p>Autofill Framework will send a {@code @non-null} {@link InlineSuggestionsRequest} if + * currently inline suggestions are supported and can be displayed. If the Autofill service + * wants to show inline suggestions, they may return {@link Dataset} with valid + * {@link InlinePresentation}.</p> + * + * <p>The Autofill Service must set supportsInlineSuggestions in its XML to enable support + * for inline suggestions.</p> * * @return the suggestionspec */ @@ -142,7 +148,7 @@ public final class FillRequest implements Parcelable { - // Code below generated by codegen v1.0.14. + // Code below generated by codegen v1.0.15. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -212,10 +218,16 @@ public final class FillRequest implements Parcelable { * @return any combination of {@link #FLAG_MANUAL_REQUEST} and * {@link #FLAG_COMPATIBILITY_MODE_REQUEST}. * @param inlineSuggestionsRequest - * Gets the {@link android.view.inputmethod.InlineSuggestionsRequest} associated + * Gets the {@link InlineSuggestionsRequest} associated * with this request. * - * TODO(b/137800469): Add more doc describing how to handle the inline suggestions request. + * <p>Autofill Framework will send a {@code @non-null} {@link InlineSuggestionsRequest} if + * currently inline suggestions are supported and can be displayed. If the Autofill service + * wants to show inline suggestions, they may return {@link Dataset} with valid + * {@link InlinePresentation}.</p> + * + * <p>The Autofill Service must set supportsInlineSuggestions in its XML to enable support + * for inline suggestions.</p> * @hide */ @DataClass.Generated.Member @@ -292,10 +304,16 @@ public final class FillRequest implements Parcelable { } /** - * Gets the {@link android.view.inputmethod.InlineSuggestionsRequest} associated + * Gets the {@link InlineSuggestionsRequest} associated * with this request. * - * TODO(b/137800469): Add more doc describing how to handle the inline suggestions request. + * <p>Autofill Framework will send a {@code @non-null} {@link InlineSuggestionsRequest} if + * currently inline suggestions are supported and can be displayed. If the Autofill service + * wants to show inline suggestions, they may return {@link Dataset} with valid + * {@link InlinePresentation}.</p> + * + * <p>The Autofill Service must set supportsInlineSuggestions in its XML to enable support + * for inline suggestions.</p> * * @return the suggestionspec */ @@ -387,8 +405,8 @@ public final class FillRequest implements Parcelable { }; @DataClass.Generated( - time = 1583196707026L, - codegenVersion = "1.0.14", + time = 1588119440090L, + codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/service/autofill/FillRequest.java", inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)") @Deprecated diff --git a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl index bed4302bcd4d..172cfef9fee2 100644 --- a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl +++ b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl @@ -28,7 +28,7 @@ import android.view.SurfaceControlViewHost; oneway interface IInlineSuggestionUiCallback { void onClick(); void onLongClick(); - void onContent(in SurfaceControlViewHost.SurfacePackage surface); + void onContent(in SurfaceControlViewHost.SurfacePackage surface, int width, int height); void onError(); void onTransferTouchFocusToImeWindow(in IBinder sourceInputToken, int displayId); void onStartIntentSender(in IntentSender intentSender); diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java index d3ad1c6b8862..19961e5efc6a 100644 --- a/core/java/android/service/autofill/InlineSuggestionRenderService.java +++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.Service; -import android.app.slice.Slice; import android.content.Intent; import android.content.IntentSender; import android.graphics.PixelFormat; @@ -34,14 +33,15 @@ import android.os.Looper; import android.os.RemoteCallback; import android.os.RemoteException; import android.util.Log; +import android.util.Size; import android.view.Display; import android.view.SurfaceControlViewHost; import android.view.View; +import android.view.ViewGroup; import android.view.WindowManager; /** - * A service that renders an inline presentation given the {@link InlinePresentation} containing - * a {@link Slice} built using the {@link androidx.autofill.AutofillSliceBuilder}. + * A service that renders an inline presentation view given the {@link InlinePresentation}. * * {@hide} */ @@ -55,8 +55,8 @@ public abstract class InlineSuggestionRenderService extends Service { * The {@link Intent} that must be declared as handled by the service. * * <p>To be supported, the service must also require the - * {@link android.Manifest.permission#BIND_INLINE_SUGGESTION_RENDER_SERVICE} permission so - * that other applications can not abuse it. + * {@link android.Manifest.permission#BIND_INLINE_SUGGESTION_RENDER_SERVICE} permission so that + * other applications can not abuse it. */ public static final String SERVICE_INTERFACE = "android.service.autofill.InlineSuggestionRenderService"; @@ -65,6 +65,45 @@ public abstract class InlineSuggestionRenderService extends Service { private IInlineSuggestionUiCallback mCallback; + /** + * If the specified {@code width}/{@code height} is an exact value, then it will be returned as + * is, otherwise the method tries to measure a size that is just large enough to fit the view + * content, within constraints posed by {@code minSize} and {@code maxSize}. + * + * @param view the view for which we measure the size + * @param width the expected width of the view, either an exact value or {@link + * ViewGroup.LayoutParams#WRAP_CONTENT} + * @param height the expected width of the view, either an exact value or {@link + * ViewGroup.LayoutParams#WRAP_CONTENT} + * @param minSize the lower bound of the size to be returned + * @param maxSize the upper bound of the size to be returned + * @return the measured size of the view based on the given size constraints. + */ + private Size measuredSize(@NonNull View view, int width, int height, @NonNull Size minSize, + @NonNull Size maxSize) { + if (width != ViewGroup.LayoutParams.WRAP_CONTENT + && height != ViewGroup.LayoutParams.WRAP_CONTENT) { + return new Size(width, height); + } + int widthMeasureSpec; + if (width == ViewGroup.LayoutParams.WRAP_CONTENT) { + widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(maxSize.getWidth(), + View.MeasureSpec.AT_MOST); + } else { + widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); + } + int heightMeasureSpec; + if (height == ViewGroup.LayoutParams.WRAP_CONTENT) { + heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(maxSize.getHeight(), + View.MeasureSpec.AT_MOST); + } else { + heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); + } + view.measure(widthMeasureSpec, heightMeasureSpec); + return new Size(Math.max(view.getMeasuredWidth(), minSize.getWidth()), + Math.max(view.getMeasuredHeight(), minSize.getHeight())); + } + private void handleRenderSuggestion(IInlineSuggestionUiCallback callback, InlinePresentation presentation, int width, int height, IBinder hostInputToken, int displayId) { @@ -82,6 +121,7 @@ public abstract class InlineSuggestionRenderService extends Service { try { final View suggestionView = onRenderSuggestion(presentation, width, height); if (suggestionView == null) { + Log.w(TAG, "ExtServices failed to render the inline suggestion view."); try { callback.onError(); } catch (RemoteException e) { @@ -90,13 +130,16 @@ public abstract class InlineSuggestionRenderService extends Service { return; } mCallback = callback; + final Size measuredSize = measuredSize(suggestionView, width, height, + presentation.getInlinePresentationSpec().getMinSize(), + presentation.getInlinePresentationSpec().getMaxSize()); + Log.v(TAG, "width=" + width + ", height=" + height + ", measuredSize=" + measuredSize); final InlineSuggestionRoot suggestionRoot = new InlineSuggestionRoot(this, callback); suggestionRoot.addView(suggestionView); - WindowManager.LayoutParams lp = - new WindowManager.LayoutParams(width, height, - WindowManager.LayoutParams.TYPE_APPLICATION, 0, - PixelFormat.TRANSPARENT); + WindowManager.LayoutParams lp = new WindowManager.LayoutParams(measuredSize.getWidth(), + measuredSize.getHeight(), WindowManager.LayoutParams.TYPE_APPLICATION, 0, + PixelFormat.TRANSPARENT); final SurfaceControlViewHost host = new SurfaceControlViewHost(this, getDisplay(), hostInputToken); @@ -124,7 +167,8 @@ public abstract class InlineSuggestionRenderService extends Service { return true; }); - sendResult(callback, host.getSurfacePackage()); + sendResult(callback, host.getSurfacePackage(), measuredSize.getWidth(), + measuredSize.getHeight()); } finally { updateDisplay(Display.DEFAULT_DISPLAY); } @@ -136,9 +180,9 @@ public abstract class InlineSuggestionRenderService extends Service { } private void sendResult(@NonNull IInlineSuggestionUiCallback callback, - @Nullable SurfaceControlViewHost.SurfacePackage surface) { + @Nullable SurfaceControlViewHost.SurfacePackage surface, int width, int height) { try { - callback.onContent(surface); + callback.onContent(surface, width, height); } catch (RemoteException e) { Log.w(TAG, "RemoteException calling onContent(" + surface + ")"); } @@ -154,10 +198,10 @@ public abstract class InlineSuggestionRenderService extends Service { public void renderSuggestion(@NonNull IInlineSuggestionUiCallback callback, @NonNull InlinePresentation presentation, int width, int height, @Nullable IBinder hostInputToken, int displayId) { - mHandler.sendMessage(obtainMessage( - InlineSuggestionRenderService::handleRenderSuggestion, - InlineSuggestionRenderService.this, callback, presentation, - width, height, hostInputToken, displayId)); + mHandler.sendMessage( + obtainMessage(InlineSuggestionRenderService::handleRenderSuggestion, + InlineSuggestionRenderService.this, callback, presentation, + width, height, hostInputToken, displayId)); } @Override @@ -176,7 +220,8 @@ public abstract class InlineSuggestionRenderService extends Service { /** * Starts the {@link IntentSender} from the client app. * - * @param intentSender the {@link IntentSender} to start the attribution UI from the client app. + * @param intentSender the {@link IntentSender} to start the attribution UI from the client + * app. */ public final void startIntentSender(@NonNull IntentSender intentSender) { if (mCallback == null) return; @@ -188,8 +233,8 @@ public abstract class InlineSuggestionRenderService extends Service { } /** - * Returns the metadata about the renderer. Returns {@code Bundle.Empty} if no metadata is - * provided. + * Returns the metadata about the renderer. Returns {@code Bundle.Empty} if no metadata is + * provided. */ @NonNull public Bundle onGetInlineSuggestionsRendererInfo() { @@ -200,8 +245,8 @@ public abstract class InlineSuggestionRenderService extends Service { * Renders the slice into a view. */ @Nullable - public View onRenderSuggestion(@NonNull InlinePresentation presentation, - int width, int height) { + public View onRenderSuggestion(@NonNull InlinePresentation presentation, int width, + int height) { Log.e(TAG, "service implementation (" + getClass() + " does not implement " + "onRenderSuggestion()"); return null; diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 5c43f8f829b0..08d990581390 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -486,15 +486,8 @@ public class StatusBarNotification implements Parcelable { /** * @hide */ - public String getShortcutId(Context context) { - String conversationId = getNotification().getShortcutId(); - if (TextUtils.isEmpty(conversationId) - && (Settings.Global.getInt(context.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 0) - && getNotification().getNotificationStyle() == Notification.MessagingStyle.class) { - conversationId = getId() + getTag() + PLACEHOLDER_CONVERSATION_ID; - } - return conversationId; + public String getShortcutId() { + return getNotification().getShortcutId(); } /** diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java index 31a085d15a34..9d0b582dddc4 100644 --- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java +++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java @@ -16,6 +16,8 @@ package android.service.quickaccesswallet; +import static android.service.quickaccesswallet.QuickAccessWalletService.ACTION_VIEW_WALLET; +import static android.service.quickaccesswallet.QuickAccessWalletService.ACTION_VIEW_WALLET_SETTINGS; import static android.service.quickaccesswallet.QuickAccessWalletService.SERVICE_INTERFACE; import android.annotation.CallbackExecutor; @@ -26,6 +28,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.IBinder; @@ -97,8 +102,7 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser @Override public boolean isWalletFeatureAvailableWhenDeviceLocked() { - return checkSecureSetting(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS) - && checkSecureSetting(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); + return checkSecureSetting(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT); } @Override @@ -234,27 +238,67 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser @Override @Nullable public Intent createWalletIntent() { - if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getWalletActivity())) { + if (mServiceInfo == null) { return null; } - return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET) - .setComponent( - new ComponentName( - mServiceInfo.getComponentName().getPackageName(), - mServiceInfo.getWalletActivity())); + String packageName = mServiceInfo.getComponentName().getPackageName(); + String walletActivity = mServiceInfo.getWalletActivity(); + return createIntent(walletActivity, packageName, ACTION_VIEW_WALLET); } @Override @Nullable public Intent createWalletSettingsIntent() { - if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getSettingsActivity())) { + if (mServiceInfo == null) { return null; } - return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET_SETTINGS) - .setComponent( - new ComponentName( - mServiceInfo.getComponentName().getPackageName(), - mServiceInfo.getSettingsActivity())); + String packageName = mServiceInfo.getComponentName().getPackageName(); + String settingsActivity = mServiceInfo.getSettingsActivity(); + return createIntent(settingsActivity, packageName, ACTION_VIEW_WALLET_SETTINGS); + } + + @Nullable + private Intent createIntent(@Nullable String activityName, String packageName, String action) { + PackageManager pm = mContext.getPackageManager(); + if (TextUtils.isEmpty(activityName)) { + activityName = queryActivityForAction(pm, packageName, action); + } + if (TextUtils.isEmpty(activityName)) { + return null; + } + ComponentName component = new ComponentName(packageName, activityName); + if (!isActivityEnabled(pm, component)) { + return null; + } + return new Intent(action).setComponent(component); + } + + @Nullable + private static String queryActivityForAction(PackageManager pm, String packageName, + String action) { + Intent intent = new Intent(action).setPackage(packageName); + ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); + if (resolveInfo == null + || resolveInfo.activityInfo == null + || !resolveInfo.activityInfo.exported) { + return null; + } + return resolveInfo.activityInfo.name; + } + + private static boolean isActivityEnabled(PackageManager pm, ComponentName component) { + int setting = pm.getComponentEnabledSetting(component); + if (setting == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { + return true; + } + if (setting != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { + return false; + } + try { + return pm.getActivityInfo(component, 0).isEnabled(); + } catch (NameNotFoundException e) { + return false; + } } @Override diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java index 834dd7b6e7d8..27c2d5c5cdc3 100644 --- a/core/java/android/view/DisplayAdjustments.java +++ b/core/java/android/view/DisplayAdjustments.java @@ -16,6 +16,8 @@ package android.view; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; @@ -27,25 +29,25 @@ public class DisplayAdjustments { public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments(); private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; - private Configuration mConfiguration; + private final Configuration mConfiguration = new Configuration(Configuration.EMPTY); @UnsupportedAppUsage public DisplayAdjustments() { } - public DisplayAdjustments(Configuration configuration) { - mConfiguration = new Configuration(configuration != null - ? configuration : Configuration.EMPTY); + public DisplayAdjustments(@Nullable Configuration configuration) { + if (configuration != null) { + mConfiguration.setTo(configuration); + } } - public DisplayAdjustments(DisplayAdjustments daj) { + public DisplayAdjustments(@NonNull DisplayAdjustments daj) { setCompatibilityInfo(daj.mCompatInfo); - mConfiguration = new Configuration(daj.mConfiguration != null - ? daj.mConfiguration : Configuration.EMPTY); + mConfiguration.setTo(daj.getConfiguration()); } @UnsupportedAppUsage - public void setCompatibilityInfo(CompatibilityInfo compatInfo) { + public void setCompatibilityInfo(@Nullable CompatibilityInfo compatInfo) { if (this == DEFAULT_DISPLAY_ADJUSTMENTS) { throw new IllegalArgumentException( "setCompatbilityInfo: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS"); @@ -62,7 +64,13 @@ public class DisplayAdjustments { return mCompatInfo; } - public void setConfiguration(Configuration configuration) { + /** + * Updates the configuration for the DisplayAdjustments with new configuration. + * Default to EMPTY configuration if new configuration is {@code null} + * @param configuration new configuration + * @throws IllegalArgumentException if trying to modify DEFAULT_DISPLAY_ADJUSTMENTS + */ + public void setConfiguration(@Nullable Configuration configuration) { if (this == DEFAULT_DISPLAY_ADJUSTMENTS) { throw new IllegalArgumentException( "setConfiguration: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS"); @@ -71,6 +79,7 @@ public class DisplayAdjustments { } @UnsupportedAppUsage + @NonNull public Configuration getConfiguration() { return mConfiguration; } diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index c0d61d473971..d369883f3ac3 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -385,7 +385,7 @@ public final class DisplayInfo implements Parcelable { displayId = source.readInt(); address = source.readParcelable(null); deviceProductInfo = source.readParcelable(null); - name = source.readString(); + name = source.readString8(); appWidth = source.readInt(); appHeight = source.readInt(); smallestNominalAppWidth = source.readInt(); @@ -418,8 +418,8 @@ public final class DisplayInfo implements Parcelable { presentationDeadlineNanos = source.readLong(); state = source.readInt(); ownerUid = source.readInt(); - ownerPackageName = source.readString(); - uniqueId = source.readString(); + ownerPackageName = source.readString8(); + uniqueId = source.readString8(); removeMode = source.readInt(); } @@ -431,7 +431,7 @@ public final class DisplayInfo implements Parcelable { dest.writeInt(displayId); dest.writeParcelable(address, flags); dest.writeParcelable(deviceProductInfo, flags); - dest.writeString(name); + dest.writeString8(name); dest.writeInt(appWidth); dest.writeInt(appHeight); dest.writeInt(smallestNominalAppWidth); @@ -462,8 +462,8 @@ public final class DisplayInfo implements Parcelable { dest.writeLong(presentationDeadlineNanos); dest.writeInt(state); dest.writeInt(ownerUid); - dest.writeString(ownerPackageName); - dest.writeString(uniqueId); + dest.writeString8(ownerPackageName); + dest.writeString8(uniqueId); dest.writeInt(removeMode); } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index b3b53f029382..58597cf3fb6d 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -161,6 +161,14 @@ interface IWindowManager SurfaceControl addShellRoot(int displayId, IWindow client, int windowType); /** + * Sets the window token sent to accessibility for a particular shell root. The + * displayId and windowType identify which shell-root to update. + * + * @param target The IWindow that accessibility service interfaces with. + */ + void setShellRootAccessibilityWindow(int displayId, int windowType, IWindow target); + + /** * Like overridePendingAppTransitionMultiThumb, but uses a future to supply the specs. This is * used for recents, where generating the thumbnails of the specs takes a non-trivial amount of * time, so we want to move that off the critical path for starting the new activity. diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java index df891303bb1d..38b6c03a02f9 100644 --- a/core/java/android/view/ImeInsetsSourceConsumer.java +++ b/core/java/android/view/ImeInsetsSourceConsumer.java @@ -217,6 +217,6 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { } private InputMethodManager getImm() { - return mController.getViewRoot().mContext.getSystemService(InputMethodManager.class); + return mController.getHost().getInputMethodManager(); } } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 43c7bede38c2..887607972bbc 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -37,9 +37,7 @@ import android.graphics.Insets; import android.graphics.Rect; import android.os.CancellationSignal; import android.os.Handler; -import android.os.RemoteException; import android.util.ArraySet; -import android.util.Log; import android.util.Pair; import android.util.SparseArray; import android.view.InsetsSourceConsumer.ShowResult; @@ -53,6 +51,7 @@ import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.view.animation.PathInterpolator; +import android.view.inputmethod.InputMethodManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; @@ -72,6 +71,91 @@ import java.util.function.BiFunction; */ public class InsetsController implements WindowInsetsController, InsetsAnimationControlCallbacks { + public interface Host { + + Handler getHandler(); + + /** + * Notifies host that {@link InsetsController#getState()} has changed. + */ + void notifyInsetsChanged(); + + void dispatchWindowInsetsAnimationPrepare(@NonNull WindowInsetsAnimation animation); + Bounds dispatchWindowInsetsAnimationStart( + @NonNull WindowInsetsAnimation animation, @NonNull Bounds bounds); + WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets, + @NonNull List<WindowInsetsAnimation> runningAnimations); + void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation); + + /** + * Requests host to apply surface params in synchronized manner. + */ + void applySurfaceParams(final SyncRtSurfaceTransactionApplier.SurfaceParams... params); + + /** + * @see ViewRootImpl#updateCompatSysUiVisibility(int, boolean, boolean) + */ + void updateCompatSysUiVisibility(@InternalInsetsType int type, boolean visible, + boolean hasControl); + + /** + * Called when insets have been modified by the client and should be reported back to WM. + */ + void onInsetsModified(InsetsState insetsState); + + /** + * @return Whether the host has any callbacks it wants to synchronize the animations with. + * If there are no callbacks, the animation will be off-loaded to another thread and + * slightly different animation curves are picked. + */ + boolean hasAnimationCallbacks(); + + /** + * @see WindowInsetsController#setSystemBarsAppearance + */ + void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask); + + /** + * @see WindowInsetsController#getSystemBarsAppearance() + */ + @Appearance int getSystemBarsAppearance(); + + /** + * @see WindowInsetsController#setSystemBarsBehavior + */ + void setSystemBarsBehavior(@Behavior int behavior); + + /** + * @see WindowInsetsController#getSystemBarsBehavior + */ + @Behavior int getSystemBarsBehavior(); + + /** + * Releases a surface and ensure that this is done after {@link #applySurfaceParams} has + * finished applying params. + */ + void releaseSurfaceControlFromRt(SurfaceControl surfaceControl); + + /** + * If this host is a view hierarchy, adds a pre-draw runnable to ensure proper ordering as + * described in {@link WindowInsetsAnimation.Callback#onPrepare}. + * + * If this host isn't a view hierarchy, the runnable can be executed immediately. + */ + void addOnPreDrawRunnable(Runnable r); + + /** + * Adds a runnbale to be executed during {@link Choreographer#CALLBACK_INSETS_ANIMATION} + * phase. + */ + void postInsetsAnimationCallback(Runnable r); + + /** + * Obtains {@link InputMethodManager} instance from host. + */ + InputMethodManager getInputMethodManager(); + } + private static final int ANIMATION_DURATION_SHOW_MS = 275; private static final int ANIMATION_DURATION_HIDE_MS = 340; @@ -346,7 +430,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private final Rect mFrame = new Rect(); private final BiFunction<InsetsController, Integer, InsetsSourceConsumer> mConsumerCreator; private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>(); - private final ViewRootImpl mViewRoot; + private final Host mHost; private final Handler mHandler; private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>(); @@ -370,8 +454,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private boolean mStartingAnimation; private int mCaptionInsetsHeight = 0; - private SyncRtSurfaceTransactionApplier mApplier; - private Runnable mPendingControlTimeout = this::abortPendingImeControlRequest; private final ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners = new ArrayList<>(); @@ -379,22 +461,22 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation /** Set of inset types for which an animation was started since last resetting this field */ private @InsetsType int mLastStartedAnimTypes; - public InsetsController(ViewRootImpl viewRoot) { - this(viewRoot, (controller, type) -> { + public InsetsController(Host host) { + this(host, (controller, type) -> { if (type == ITYPE_IME) { return new ImeInsetsSourceConsumer(controller.mState, Transaction::new, controller); } else { return new InsetsSourceConsumer(type, controller.mState, Transaction::new, controller); } - }, viewRoot.mHandler); + }, host.getHandler()); } @VisibleForTesting - public InsetsController(ViewRootImpl viewRoot, + public InsetsController(Host host, BiFunction<InsetsController, Integer, InsetsSourceConsumer> consumerCreator, Handler handler) { - mViewRoot = viewRoot; + mHost = host; mConsumerCreator = consumerCreator; mHandler = handler; mAnimCallback = () -> { @@ -402,10 +484,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mRunningAnimations.isEmpty()) { return; } - if (mViewRoot.mView == null) { - // The view has already detached from window. - return; - } mTmpFinishedControls.clear(); mTmpRunningAnims.clear(); @@ -433,8 +511,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeSystemBars(), mLastDisplayCutout, mLastLegacySoftInputMode, mLastLegacySystemUiFlags, null /* typeSideMap */); - mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets, - mUnmodifiableTmpRunningAnims); + mHost.dispatchWindowInsetsAnimationProgress(insets, mUnmodifiableTmpRunningAnims); for (int i = mTmpFinishedControls.size() - 1; i >= 0; i--) { dispatchAnimationEnd(mTmpFinishedControls.get(i).getAnimation()); @@ -447,7 +524,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mFrame.equals(frame)) { return; } - mViewRoot.notifyInsetsChanged(); + mHost.notifyInsetsChanged(); mFrame.set(frame); } @@ -476,7 +553,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mLastDispachedState.set(state, true /* copySources */); applyLocalVisibilityOverride(); if (localStateChanged) { - mViewRoot.notifyInsetsChanged(); + mHost.notifyInsetsChanged(); } if (!mState.equals(mLastDispachedState, true /* excludingCaptionInsets */)) { sendStateToWindowManager(); @@ -733,7 +810,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation final InsetsAnimationControlRunner runner = useInsetsAnimationThread ? new InsetsAnimationThreadControlRunner(controls, frame, mState, listener, typesReady, this, durationMs, interpolator, - animationType, mViewRoot.mHandler) + animationType, mHost.getHandler()) : new InsetsAnimationControlImpl(controls, frame, mState, listener, typesReady, this, durationMs, interpolator, animationType); @@ -860,21 +937,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public void applySurfaceParams(final SyncRtSurfaceTransactionApplier.SurfaceParams... params) { - if (mApplier == null) { - if (mViewRoot.mView == null) { - throw new IllegalStateException("View of the ViewRootImpl is not initiated."); - } - mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView); - } - if (mViewRoot.mView.isHardwareAccelerated()) { - mApplier.scheduleApply(false /* earlyWakeup */, params); - } else { - // Window doesn't support hardware acceleration, no synchronization for now. - // TODO(b/149342281): use mViewRoot.mSurface.getNextFrameNumber() to sync on every - // frame instead. - mApplier.applyParams(new Transaction(), -1 /* frame */, false /* earlyWakeup */, - params); - } + mHost.applySurfaceParams(params); } void notifyControlRevoked(InsetsSourceConsumer consumer) { @@ -900,7 +963,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation ArraySet<Integer> types = toInternalType(control.getTypes()); for (int j = types.size() - 1; j >= 0; j--) { if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) { - mViewRoot.notifyInsetsChanged(); + mHost.notifyInsetsChanged(); } } break; @@ -928,7 +991,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @VisibleForTesting public void notifyVisibilityChanged() { - mViewRoot.notifyInsetsChanged(); + mHost.notifyInsetsChanged(); sendStateToWindowManager(); } @@ -937,7 +1000,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation */ public void updateCompatSysUiVisibility(@InternalInsetsType int type, boolean visible, boolean hasControl) { - mViewRoot.updateCompatSysUiVisibility(type, visible, hasControl); + mHost.updateCompatSysUiVisibility(type, visible, hasControl); } /** @@ -954,10 +1017,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation getSourceConsumer(ITYPE_IME).onWindowFocusLost(); } - ViewRootImpl getViewRoot() { - return mViewRoot; - } - /** * Used by {@link ImeInsetsSourceConsumer} when IME decides to be shown/hidden. * @hide @@ -994,21 +1053,17 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation tmpState.addSource(mState.getSource(consumer.getType())); } } - - try { - mViewRoot.mWindowSession.insetsModified(mViewRoot.mWindow, tmpState); - } catch (RemoteException e) { - Log.e(TAG, "Failed to call insetsModified", e); - } + mHost.onInsetsModified(tmpState); } - private void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme) { + @VisibleForTesting + public void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme) { if (types == 0) { // nothing to animate. return; } - boolean hasAnimationCallbacks = hasAnimationCallbacks(); + boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks(); final InternalAnimationControlListener listener = new InternalAnimationControlListener(show, hasAnimationCallbacks, types); @@ -1023,13 +1078,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } - private boolean hasAnimationCallbacks() { - if (mViewRoot.mView == null) { - return false; - } - return mViewRoot.mView.hasWindowInsetsAnimationCallback(); - } - private void hideDirectly( @InsetsType int types, boolean animationFinished, @AnimationType int animationType) { final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types); @@ -1063,37 +1111,28 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation public void startAnimation(InsetsAnimationControlImpl controller, WindowInsetsAnimationControlListener listener, int types, WindowInsetsAnimation animation, Bounds bounds) { - if (mViewRoot.mView == null) { - return; - } - mViewRoot.mView.dispatchWindowInsetsAnimationPrepare(animation); - mViewRoot.mView.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() { - @Override - public boolean onPreDraw() { - mViewRoot.mView.getViewTreeObserver().removeOnPreDrawListener(this); - if (controller.isCancelled()) { - return true; - } - for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { - RunningAnimation runningAnimation = mRunningAnimations.get(i); - if (runningAnimation.runner == controller) { - runningAnimation.startDispatched = true; - } + mHost.dispatchWindowInsetsAnimationPrepare(animation); + mHost.addOnPreDrawRunnable(() -> { + if (controller.isCancelled()) { + return; + } + for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { + RunningAnimation runningAnimation = mRunningAnimations.get(i); + if (runningAnimation.runner == controller) { + runningAnimation.startDispatched = true; } - mViewRoot.mView.dispatchWindowInsetsAnimationStart(animation, bounds); - mStartingAnimation = true; - controller.mReadyDispatched = true; - listener.onReady(controller, types); - mStartingAnimation = false; - return true; } + mHost.dispatchWindowInsetsAnimationStart(animation, bounds); + mStartingAnimation = true; + controller.mReadyDispatched = true; + listener.onReady(controller, types); + mStartingAnimation = false; }); - mViewRoot.mView.invalidate(); } @VisibleForTesting public void dispatchAnimationEnd(WindowInsetsAnimation animation) { - mViewRoot.mView.dispatchWindowInsetsAnimationEnd(animation); + mHost.dispatchWindowInsetsAnimationEnd(animation); } @VisibleForTesting @@ -1105,30 +1144,19 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return; } if (!mAnimCallbackScheduled) { - mViewRoot.mChoreographer.postCallback(Choreographer.CALLBACK_INSETS_ANIMATION, - mAnimCallback, null /* token*/); + mHost.postInsetsAnimationCallback(mAnimCallback); mAnimCallbackScheduled = true; } } @Override public void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask) { - mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_APPEARANCE_CONTROLLED; - final InsetsFlags insetsFlags = mViewRoot.mWindowAttributes.insetsFlags; - if (insetsFlags.appearance != appearance) { - insetsFlags.appearance = (insetsFlags.appearance & ~mask) | (appearance & mask); - mViewRoot.mWindowAttributesChanged = true; - mViewRoot.scheduleTraversals(); - } + mHost.setSystemBarsAppearance(appearance, mask); } @Override public @Appearance int getSystemBarsAppearance() { - if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) { - // We only return the requested appearance, not the implied one. - return 0; - } - return mViewRoot.mWindowAttributes.insetsFlags.appearance; + return mHost.getSystemBarsAppearance(); } @Override @@ -1138,21 +1166,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public void setSystemBarsBehavior(@Behavior int behavior) { - mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED; - if (mViewRoot.mWindowAttributes.insetsFlags.behavior != behavior) { - mViewRoot.mWindowAttributes.insetsFlags.behavior = behavior; - mViewRoot.mWindowAttributesChanged = true; - mViewRoot.scheduleTraversals(); - } + mHost.setSystemBarsBehavior(behavior); } @Override public @Appearance int getSystemBarsBehavior() { - if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) == 0) { - // We only return the requested behavior, not the implied one. - return 0; - } - return mViewRoot.mWindowAttributes.insetsFlags.behavior; + return mHost.getSystemBarsBehavior(); } private @InsetsType int calculateControllableTypes() { @@ -1197,22 +1216,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mControllableInsetsChangedListeners.remove(listener); } - /** - * At the time we receive new leashes (e.g. InsetsSourceConsumer is processing - * setControl) we need to release the old leash. But we may have already scheduled - * a SyncRtSurfaceTransaction applier to use it from the RenderThread. To avoid - * synchronization issues we also release from the RenderThread so this release - * happens after any existing items on the work queue. - */ + @Override public void releaseSurfaceControlFromRt(SurfaceControl sc) { - if (mViewRoot.mView != null && mViewRoot.mView.isHardwareAccelerated()) { - mViewRoot.registerRtFrameCallback(frame -> { - sc.release(); - }); - // Make sure a frame gets scheduled. - mViewRoot.mView.invalidate(); - } else { - sc.release(); - } + mHost.releaseSurfaceControlFromRt(sc); + } + + Host getHost() { + return mHost; } } diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java index 033ccef3666d..b0158467a17b 100644 --- a/core/java/android/view/InsetsSource.java +++ b/core/java/android/view/InsetsSource.java @@ -116,15 +116,15 @@ public class InsetsSource implements Parcelable { if (!ignoreVisibility && !mVisible) { return Insets.NONE; } - if (!getIntersection(frame, relativeFrame, mTmpFrame)) { - return Insets.NONE; - } // During drag-move and drag-resizing, the caption insets position may not get updated // before the app frame get updated. To layout the app content correctly during drag events, // we always return the insets with the corresponding height covering the top. if (getType() == ITYPE_CAPTION_BAR) { return Insets.of(0, frame.height(), 0, 0); } + if (!getIntersection(frame, relativeFrame, mTmpFrame)) { + return Insets.NONE; + } // TODO: Currently, non-floating IME always intersects at bottom due to issues with cutout. // However, we should let the policy decide from the server. @@ -136,20 +136,25 @@ public class InsetsSource implements Parcelable { if (mTmpFrame.width() == relativeFrame.width()) { if (mTmpFrame.top == relativeFrame.top) { return Insets.of(0, mTmpFrame.height(), 0, 0); - } else { + } else if (mTmpFrame.bottom == relativeFrame.bottom) { return Insets.of(0, 0, 0, mTmpFrame.height()); } + // TODO: remove when insets are shell-customizable. + // This is a hack that says "if this is a top-inset (eg statusbar), always apply it + // to the top". It is used when adjusting primary split for IME. + if (mTmpFrame.top == 0) { + return Insets.of(0, mTmpFrame.height(), 0, 0); + } } // Intersecting at left/right else if (mTmpFrame.height() == relativeFrame.height()) { if (mTmpFrame.left == relativeFrame.left) { return Insets.of(mTmpFrame.width(), 0, 0, 0); - } else { + } else if (mTmpFrame.right == relativeFrame.right) { return Insets.of(0, 0, mTmpFrame.width(), 0); } - } else { - return Insets.NONE; } + return Insets.NONE; } /** @@ -208,8 +213,16 @@ public class InsetsSource implements Parcelable { public InsetsSource(Parcel in) { mType = in.readInt(); - mFrame = in.readParcelable(null /* loader */); - mVisibleFrame = in.readParcelable(null /* loader */); + if (in.readInt() != 0) { + mFrame = Rect.CREATOR.createFromParcel(in); + } else { + mFrame = null; + } + if (in.readInt() != 0) { + mVisibleFrame = Rect.CREATOR.createFromParcel(in); + } else { + mVisibleFrame = null; + } mVisible = in.readBoolean(); } @@ -221,8 +234,18 @@ public class InsetsSource implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); - dest.writeParcelable(mFrame, 0 /* flags*/); - dest.writeParcelable(mVisibleFrame, 0 /* flags */); + if (mFrame != null) { + dest.writeInt(1); + mFrame.writeToParcel(dest, 0); + } else { + dest.writeInt(0); + } + if (mVisibleFrame != null) { + dest.writeInt(1); + mVisibleFrame.writeToParcel(dest, 0); + } else { + dest.writeInt(0); + } dest.writeBoolean(mVisible); } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 76ed37c51bfe..0625806e40ef 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -894,7 +894,7 @@ public final class SurfaceControl implements Parcelable { throw new IllegalArgumentException("source must not be null"); } - mName = in.readString(); + mName = in.readString8(); mWidth = in.readInt(); mHeight = in.readInt(); @@ -912,7 +912,7 @@ public final class SurfaceControl implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mName); + dest.writeString8(mName); dest.writeInt(mWidth); dest.writeInt(mHeight); if (mNativeObject == 0) { diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index cfceb031539f..3d6da6f71b3f 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -39,7 +39,7 @@ import java.util.Objects; * {@link SurfaceView#setChildSurfacePackage}. */ public class SurfaceControlViewHost { - private ViewRootImpl mViewRoot; + private final ViewRootImpl mViewRoot; private WindowlessWindowManager mWm; private SurfaceControl mSurfaceControl; @@ -226,6 +226,14 @@ public class SurfaceControlViewHost { } /** + * @return the ViewRootImpl wrapped by this host. + * @hide + */ + public IWindow getWindowToken() { + return mViewRoot.mWindow; + } + + /** * @hide */ @TestApi diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f98c1f660cfa..310299910e96 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -11519,6 +11519,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, ViewParent parent = getParent(); if (parent instanceof View) { return ((View) parent).getWindowInsetsController(); + } else if (parent instanceof ViewRootImpl) { + // Between WindowManager.addView() and the first traversal AttachInfo isn't set yet. + return ((ViewRootImpl) parent).getInsetsController(); } return null; } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9d275cdcb00f..b74c8f641a76 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -327,6 +327,8 @@ public final class ViewRootImpl implements ViewParent, private boolean mForceNextConfigUpdate; private boolean mUseBLASTAdapter; + private boolean mForceDisableBLAST; + private boolean mEnableTripleBuffering; /** * Signals that compatibility booleans have been initialized according to @@ -755,7 +757,7 @@ public final class ViewRootImpl implements ViewParent, mChoreographer = useSfChoreographer ? Choreographer.getSfInstance() : Choreographer.getInstance(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); - mInsetsController = new InsetsController(this); + mInsetsController = new InsetsController(new ViewRootInsetsControllerHost(this)); String processorOverrideName = context.getResources().getString( R.string.config_inputEventCompatProcessorOverrideClassName); @@ -784,7 +786,6 @@ public final class ViewRootImpl implements ViewParent, loadSystemProperties(); mImeFocusController = new ImeFocusController(this); - mUseBLASTAdapter = WindowManagerGlobal.useBLAST(); } public static void addFirstDrawHandler(Runnable callback) { @@ -925,10 +926,9 @@ public final class ViewRootImpl implements ViewParent, if (mWindowAttributes.packageName == null) { mWindowAttributes.packageName = mBasePackageName; } - if (mUseBLASTAdapter) { - mWindowAttributes.privateFlags |= + mWindowAttributes.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST; - } + attrs = mWindowAttributes; setTag(); @@ -1102,6 +1102,13 @@ public final class ViewRootImpl implements ViewParent, "Unable to add window -- unknown error code " + res); } + if ((res & WindowManagerGlobal.ADD_FLAG_USE_BLAST) != 0) { + mUseBLASTAdapter = true; + } + if ((res & WindowManagerGlobal.ADD_FLAG_USE_TRIPLE_BUFFERING) != 0) { + mEnableTripleBuffering = true; + } + if (view instanceof RootViewSurfaceTaker) { mInputQueueCallback = ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue(); @@ -1414,10 +1421,8 @@ public final class ViewRootImpl implements ViewParent, } mWindowAttributes.privateFlags |= compatibleWindowFlag; - if (mUseBLASTAdapter) { - mWindowAttributes.privateFlags |= + mWindowAttributes.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST; - } if (mWindowAttributes.preservePreviousSurfaceInsets) { // Restore old surface insets. @@ -1784,12 +1789,13 @@ public final class ViewRootImpl implements ViewParent, Surface ret = null; if (mBlastBufferQueue == null) { mBlastBufferQueue = new BLASTBufferQueue( - mBlastSurfaceControl, width, height); + mBlastSurfaceControl, width, height, mEnableTripleBuffering); // We only return the Surface the first time, as otherwise // it hasn't changed and there is no need to update. ret = mBlastBufferQueue.getSurface(); + } else { + mBlastBufferQueue.update(mBlastSurfaceControl, width, height); } - mBlastBufferQueue.update(mBlastSurfaceControl, width, height); return ret; } @@ -7393,7 +7399,7 @@ public final class ViewRootImpl implements ViewParent, mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls, mSurfaceSize, mBlastSurfaceControl); if (mSurfaceControl.isValid()) { - if (!mUseBLASTAdapter) { + if (!useBLAST()) { mSurface.copyFrom(mSurfaceControl); } else { final Surface blastSurface = getOrCreateBLASTSurface(mSurfaceSize.x, @@ -9760,7 +9766,7 @@ public final class ViewRootImpl implements ViewParent, * @hide */ public SurfaceControl getRenderSurfaceControl() { - if (mUseBLASTAdapter) { + if (useBLAST()) { return mBlastSurfaceControl; } else { return mSurfaceControl; @@ -9777,11 +9783,11 @@ public final class ViewRootImpl implements ViewParent, * flag. Needs to be called before addView. */ void forceDisableBLAST() { - mUseBLASTAdapter = false; + mForceDisableBLAST = true; } boolean useBLAST() { - return mUseBLASTAdapter; + return mUseBLASTAdapter && !mForceDisableBLAST; } /** diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java new file mode 100644 index 000000000000..d8bf58f78339 --- /dev/null +++ b/core/java/android/view/ViewRootInsetsControllerHost.java @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED; + +import android.annotation.NonNull; +import android.os.Handler; +import android.os.RemoteException; +import android.util.Log; +import android.view.inputmethod.InputMethodManager; + +import java.util.List; + +/** + * Implements {@link InsetsController.Host} for {@link ViewRootImpl}s. + * @hide + */ +public class ViewRootInsetsControllerHost implements InsetsController.Host { + + private final String TAG = "VRInsetsControllerHost"; + + private final ViewRootImpl mViewRoot; + private SyncRtSurfaceTransactionApplier mApplier; + + public ViewRootInsetsControllerHost(ViewRootImpl viewRoot) { + mViewRoot = viewRoot; + } + + @Override + public Handler getHandler() { + return mViewRoot.mHandler; + } + + @Override + public void notifyInsetsChanged() { + mViewRoot.notifyInsetsChanged(); + } + + @Override + public void addOnPreDrawRunnable(Runnable r) { + if (mViewRoot.mView == null) { + return; + } + mViewRoot.mView.getViewTreeObserver().addOnPreDrawListener( + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + mViewRoot.mView.getViewTreeObserver().removeOnPreDrawListener(this); + r.run(); + return true; + } + }); + mViewRoot.mView.invalidate(); + } + + @Override + public void dispatchWindowInsetsAnimationPrepare(@NonNull WindowInsetsAnimation animation) { + if (mViewRoot.mView == null) { + return; + } + mViewRoot.mView.dispatchWindowInsetsAnimationPrepare(animation); + } + + @Override + public WindowInsetsAnimation.Bounds dispatchWindowInsetsAnimationStart( + @NonNull WindowInsetsAnimation animation, + @NonNull WindowInsetsAnimation.Bounds bounds) { + if (mViewRoot.mView == null) { + return null; + } + return mViewRoot.mView.dispatchWindowInsetsAnimationStart(animation, bounds); + } + + @Override + public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets, + @NonNull List<WindowInsetsAnimation> runningAnimations) { + if (mViewRoot.mView == null) { + // The view has already detached from window. + return null; + } + return mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets, runningAnimations); + } + + @Override + public void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation) { + mViewRoot.mView.dispatchWindowInsetsAnimationEnd(animation); + } + + @Override + public void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params) { + if (mApplier == null) { + if (mViewRoot.mView == null) { + throw new IllegalStateException("View of the ViewRootImpl is not initiated."); + } + mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView); + } + if (mViewRoot.mView.isHardwareAccelerated()) { + mApplier.scheduleApply(false /* earlyWakeup */, params); + } else { + // Window doesn't support hardware acceleration, no synchronization for now. + // TODO(b/149342281): use mViewRoot.mSurface.getNextFrameNumber() to sync on every + // frame instead. + mApplier.applyParams(new SurfaceControl.Transaction(), -1 /* frame */, + false /* earlyWakeup */, params); + } + } + + @Override + public void postInsetsAnimationCallback(Runnable r) { + mViewRoot.mChoreographer.postCallback(Choreographer.CALLBACK_INSETS_ANIMATION, r, + null /* token */); + } + + @Override + public void updateCompatSysUiVisibility(int type, boolean visible, boolean hasControl) { + mViewRoot.updateCompatSysUiVisibility(type, visible, hasControl); + } + + @Override + public void onInsetsModified(InsetsState insetsState) { + try { + mViewRoot.mWindowSession.insetsModified(mViewRoot.mWindow, insetsState); + } catch (RemoteException e) { + Log.e(TAG, "Failed to call insetsModified", e); + } + } + + @Override + public boolean hasAnimationCallbacks() { + if (mViewRoot.mView == null) { + return false; + } + return mViewRoot.mView.hasWindowInsetsAnimationCallback(); + } + + @Override + public void setSystemBarsAppearance(int appearance, int mask) { + mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_APPEARANCE_CONTROLLED; + final InsetsFlags insetsFlags = mViewRoot.mWindowAttributes.insetsFlags; + if (insetsFlags.appearance != appearance) { + insetsFlags.appearance = (insetsFlags.appearance & ~mask) | (appearance & mask); + mViewRoot.mWindowAttributesChanged = true; + mViewRoot.scheduleTraversals(); + } + } + + @Override + public int getSystemBarsAppearance() { + if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) { + // We only return the requested appearance, not the implied one. + return 0; + } + return mViewRoot.mWindowAttributes.insetsFlags.appearance; + } + + @Override + public void setSystemBarsBehavior(int behavior) { + mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED; + if (mViewRoot.mWindowAttributes.insetsFlags.behavior != behavior) { + mViewRoot.mWindowAttributes.insetsFlags.behavior = behavior; + mViewRoot.mWindowAttributesChanged = true; + mViewRoot.scheduleTraversals(); + } + } + + @Override + public int getSystemBarsBehavior() { + if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) == 0) { + // We only return the requested behavior, not the implied one. + return 0; + } + return mViewRoot.mWindowAttributes.insetsFlags.behavior; + } + + @Override + public void releaseSurfaceControlFromRt(SurfaceControl surfaceControl) { + + // At the time we receive new leashes (e.g. InsetsSourceConsumer is processing + // setControl) we need to release the old leash. But we may have already scheduled + // a SyncRtSurfaceTransaction applier to use it from the RenderThread. To avoid + // synchronization issues we also release from the RenderThread so this release + // happens after any existing items on the work queue. + + if (mViewRoot.mView != null && mViewRoot.mView.isHardwareAccelerated()) { + mViewRoot.registerRtFrameCallback(frame -> { + surfaceControl.release(); + }); + // Make sure a frame gets scheduled. + mViewRoot.mView.invalidate(); + } else { + surfaceControl.release(); + } + } + + @Override + public InputMethodManager getInputMethodManager() { + return mViewRoot.mContext.getSystemService(InputMethodManager.class); + } +} diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 94591eafe72d..8490f2abeffa 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -124,8 +124,10 @@ public final class WindowManagerGlobal { */ public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2; + public static final int ADD_FLAG_IN_TOUCH_MODE = 0x1; public static final int ADD_FLAG_APP_VISIBLE = 0x2; - public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE; + public static final int ADD_FLAG_USE_TRIPLE_BUFFERING = 0x4; + public static final int ADD_FLAG_USE_BLAST = 0x8; /** * Like {@link #RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS}, but as a "hint" when adding the diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 2975d5ee8e1c..28a18da37b3e 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -36,6 +36,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import java.util.List; @@ -69,7 +70,8 @@ import java.util.List; public final class WindowManagerImpl implements WindowManager { @UnsupportedAppUsage private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance(); - private final Context mContext; + @VisibleForTesting + public final Context mContext; private final Window mParentWindow; private IBinder mDefaultToken; diff --git a/core/java/android/view/inputmethod/InlineSuggestion.java b/core/java/android/view/inputmethod/InlineSuggestion.java index f50f0dea0466..6b1a480986c8 100644 --- a/core/java/android/view/inputmethod/InlineSuggestion.java +++ b/core/java/android/view/inputmethod/InlineSuggestion.java @@ -29,6 +29,7 @@ import android.os.RemoteException; import android.util.Size; import android.util.Slog; import android.view.SurfaceControlViewHost; +import android.view.ViewGroup; import android.widget.inline.InlineContentView; import com.android.internal.util.DataClass; @@ -94,19 +95,26 @@ public final class InlineSuggestion implements Parcelable { /** * Inflates a view with the content of this suggestion at a specific size. - * The size must be between the + * + * <p> The size must be either 1) between the * {@link android.widget.inline.InlinePresentationSpec#getMinSize() min size} and the * {@link android.widget.inline.InlinePresentationSpec#getMaxSize() max size} of the - * presentation spec returned by {@link InlineSuggestionInfo#getInlinePresentationSpec()}. + * presentation spec returned by {@link InlineSuggestionInfo#getInlinePresentationSpec()}, + * or 2) {@link ViewGroup.LayoutParams#WRAP_CONTENT}. If the size is set to + * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, then the size of the inflated view will be just + * large enough to fit the content, while still conforming to the min / max size specified by + * the {@link android.widget.inline.InlinePresentationSpec}. * * <p> The caller can attach an {@link android.view.View.OnClickListener} and/or an * {@link android.view.View.OnLongClickListener} to the view in the - * {@code callback} to receive click and - * long click events on the view. + * {@code callback} to receive click and long click events on the view. * * @param context Context in which to inflate the view. - * @param size The size at which to inflate the suggestion. - * @param callback Callback for receiving the inflated view. + * @param size The size at which to inflate the suggestion. For each dimension, it maybe + * an exact value or {@link ViewGroup.LayoutParams#WRAP_CONTENT}. + * @param callback Callback for receiving the inflated view, where the + * {@link ViewGroup.LayoutParams} of the view is set as the actual size of + * the underlying remote view. * @throws IllegalArgumentException If an invalid argument is passed. * @throws IllegalStateException If this method is already called. */ @@ -115,10 +123,11 @@ public final class InlineSuggestion implements Parcelable { @NonNull Consumer<InlineContentView> callback) { final Size minSize = mInfo.getInlinePresentationSpec().getMinSize(); final Size maxSize = mInfo.getInlinePresentationSpec().getMaxSize(); - if (size.getHeight() < minSize.getHeight() || size.getHeight() > maxSize.getHeight() - || size.getWidth() < minSize.getWidth() || size.getWidth() > maxSize.getWidth()) { - throw new IllegalArgumentException("size not between min:" - + minSize + " and max:" + maxSize); + if (!isValid(size.getWidth(), minSize.getWidth(), maxSize.getWidth()) + || !isValid(size.getHeight(), minSize.getHeight(), maxSize.getHeight())) { + throw new IllegalArgumentException( + "size is neither between min:" + minSize + " and max:" + maxSize + + ", nor wrap_content"); } mInlineContentCallback = getInlineContentCallback(context, callbackExecutor, callback); AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { @@ -136,6 +145,17 @@ public final class InlineSuggestion implements Parcelable { }); } + /** + * Returns true if the {@code actual} length is within [min, max] or is {@link + * ViewGroup.LayoutParams#WRAP_CONTENT}. + */ + private static boolean isValid(int actual, int min, int max) { + if (actual == ViewGroup.LayoutParams.WRAP_CONTENT) { + return true; + } + return actual >= min && actual <= max; + } + private synchronized InlineContentCallbackImpl getInlineContentCallback(Context context, Executor callbackExecutor, Consumer<InlineContentView> callback) { if (mInlineContentCallback != null) { @@ -154,10 +174,11 @@ public final class InlineSuggestion implements Parcelable { @Override @BinderThread - public void onContent(SurfaceControlViewHost.SurfacePackage content) { + public void onContent(SurfaceControlViewHost.SurfacePackage content, int width, + int height) { final InlineContentCallbackImpl callbackImpl = mCallbackImpl.get(); if (callbackImpl != null) { - callbackImpl.onContent(content); + callbackImpl.onContent(content, width, height); } } @@ -196,11 +217,13 @@ public final class InlineSuggestion implements Parcelable { } @BinderThread - public void onContent(SurfaceControlViewHost.SurfacePackage content) { + public void onContent(SurfaceControlViewHost.SurfacePackage content, int width, + int height) { if (content == null) { mCallbackExecutor.execute(() -> mCallback.accept(/* view */null)); } else { mView = new InlineContentView(mContext); + mView.setLayoutParams(new ViewGroup.LayoutParams(width, height)); mView.setChildSurfacePackage(content); mCallbackExecutor.execute(() -> mCallback.accept(mView)); } @@ -398,10 +421,10 @@ public final class InlineSuggestion implements Parcelable { }; @DataClass.Generated( - time = 1585180783541L, + time = 1587771173367L, codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestion.java", - inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nprivate synchronized android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") + inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nprivate static boolean isValid(int,int,int)\nprivate synchronized android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 71dd6653f6a6..3cf61098f11c 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -645,11 +645,6 @@ public final class InputMethodManager { @Override public void setCurrentRootView(ViewRootImpl rootView) { synchronized (mH) { - if (mCurRootView != null) { - // Reset the last served view and restart window focus state of the root view. - mCurRootView.getImeFocusController().setServedView(null); - mRestartOnNextWindowFocus = true; - } mCurRootView = rootView; } } diff --git a/core/java/android/widget/ImeAwareEditText.java b/core/java/android/widget/ImeAwareEditText.java new file mode 100644 index 000000000000..9cd458558de3 --- /dev/null +++ b/core/java/android/widget/ImeAwareEditText.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; + +/** + * EditText that keeps track of the IME state, specifically its input connection. This is useful + * for clients who request the IME before the system has established a connection. + * @hide + */ +public class ImeAwareEditText extends EditText { + private boolean mHasPendingShowSoftInputRequest; + final Runnable mRunShowSoftInputIfNecessary = () -> showSoftInputIfNecessary(); + + public ImeAwareEditText(Context context) { + super(context, null); + } + + public ImeAwareEditText(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + /** + * This method is called back by the system when the system is about to establish a connection + * to the current input method. + * + * <p>This is a good and reliable signal to schedule a pending task to call + * {@link InputMethodManager#showSoftInput(View, int)}.</p> + * + * @param editorInfo context about the text input field. + * @return {@link InputConnection} to be passed to the input method. + */ + @Override + public InputConnection onCreateInputConnection(EditorInfo editorInfo) { + final InputConnection ic = super.onCreateInputConnection(editorInfo); + if (mHasPendingShowSoftInputRequest) { + removeCallbacks(mRunShowSoftInputIfNecessary); + post(mRunShowSoftInputIfNecessary); + } + return ic; + } + + private void showSoftInputIfNecessary() { + if (mHasPendingShowSoftInputRequest) { + final InputMethodManager imm = + getContext().getSystemService(InputMethodManager.class); + imm.showSoftInput(this, 0); + mHasPendingShowSoftInputRequest = false; + } + } + + public void scheduleShowSoftInput() { + final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class); + if (imm.isActive(this)) { + // This means that ImeAwareEditText is already connected to the IME. + // InputMethodManager#showSoftInput() is guaranteed to pass client-side focus check. + mHasPendingShowSoftInputRequest = false; + removeCallbacks(mRunShowSoftInputIfNecessary); + imm.showSoftInput(this, 0); + return; + } + + // Otherwise, InputMethodManager#showSoftInput() should be deferred after + // onCreateInputConnection(). + mHasPendingShowSoftInputRequest = true; + } +} diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 6425cf11ccb3..4311ffbe0e95 100755 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -746,6 +746,15 @@ public class ListPopupWindow implements ShowableListMenu { } /** + * Remove existing exit transition from PopupWindow and force immediate dismissal. + * @hide + */ + public void dismissImmediate() { + mPopup.setExitTransition(null); + dismiss(); + } + + /** * Set a listener to receive a callback when the popup is dismissed. * * @param listener Listener that will be notified when the popup is dismissed. diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index a069e643afcb..e07181abe19c 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -90,7 +90,7 @@ public final class SelectionActionModeHelper { mTextView = mEditor.getTextView(); mTextClassificationHelper = new TextClassificationHelper( mTextView.getContext(), - mTextView::getTextClassifier, + mTextView::getTextClassificationSession, getText(mTextView), 0, 1, mTextView.getTextLocales()); mSelectionTracker = new SelectionTracker(mTextView); @@ -500,7 +500,7 @@ public final class SelectionActionModeHelper { selectionEnd = sortedSelectionIndices[1]; } mTextClassificationHelper.init( - mTextView::getTextClassifier, + mTextView::getTextClassificationSession, getText(mTextView), selectionStart, selectionEnd, mTextView.getTextLocales()); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index ec07574f141f..29914aababe3 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -12626,7 +12626,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return getTextClassifier() == TextClassifier.NO_OP; } - /** * Starts an ActionMode for the specified TextLinkSpan. * @@ -12670,7 +12669,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setDefaultLocales(getTextLocales()) .build(); final Supplier<TextClassification> supplier = () -> - getTextClassifier().classifyText(request); + getTextClassificationSession().classifyText(request); final Consumer<TextClassification> consumer = classification -> { if (classification != null) { if (!classification.getActions().isEmpty()) { diff --git a/core/java/android/window/DisplayAreaInfo.java b/core/java/android/window/DisplayAreaInfo.java index 0d35bcafdf45..358467ff599f 100644 --- a/core/java/android/window/DisplayAreaInfo.java +++ b/core/java/android/window/DisplayAreaInfo.java @@ -43,15 +43,19 @@ public final class DisplayAreaInfo implements Parcelable { */ public final int displayId; - public DisplayAreaInfo(@NonNull WindowContainerToken token, int displayId) { + public final int featureId; + + public DisplayAreaInfo(@NonNull WindowContainerToken token, int displayId, int featureId) { this.token = token; this.displayId = displayId; + this.featureId = featureId; } private DisplayAreaInfo(Parcel in) { token = WindowContainerToken.CREATOR.createFromParcel(in); configuration.readFromParcel(in); displayId = in.readInt(); + featureId = in.readInt(); } @Override @@ -59,6 +63,7 @@ public final class DisplayAreaInfo implements Parcelable { token.writeToParcel(dest, flags); configuration.writeToParcel(dest, flags); dest.writeInt(displayId); + dest.writeInt(featureId); } @NonNull diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java index f3ef5a0c0aa2..a2fd128e2246 100644 --- a/core/java/android/window/DisplayAreaOrganizer.java +++ b/core/java/android/window/DisplayAreaOrganizer.java @@ -21,6 +21,7 @@ import android.annotation.RequiresPermission; import android.annotation.TestApi; import android.os.RemoteException; import android.util.Singleton; +import android.view.SurfaceControl; /** * Interface for WindowManager to delegate control of display areas. @@ -64,7 +65,8 @@ public class DisplayAreaOrganizer extends WindowOrganizer { } } - public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo) {} + public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo, + @NonNull SurfaceControl leash) {} public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {} @@ -76,8 +78,9 @@ public class DisplayAreaOrganizer extends WindowOrganizer { private final IDisplayAreaOrganizer mInterface = new IDisplayAreaOrganizer.Stub() { @Override - public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo) { - DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayAreaInfo); + public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo, + @NonNull SurfaceControl leash) { + DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayAreaInfo, leash); } @Override diff --git a/core/java/android/window/IDisplayAreaOrganizer.aidl b/core/java/android/window/IDisplayAreaOrganizer.aidl index 39a9235a4224..5e3e5e8e7d42 100644 --- a/core/java/android/window/IDisplayAreaOrganizer.aidl +++ b/core/java/android/window/IDisplayAreaOrganizer.aidl @@ -17,13 +17,14 @@ package android.window; import android.window.DisplayAreaInfo; +import android.view.SurfaceControl; /** * Interface for WindowManager to delegate control of display areas. * {@hide} */ oneway interface IDisplayAreaOrganizer { - void onDisplayAreaAppeared(in DisplayAreaInfo displayAreaInfo); + void onDisplayAreaAppeared(in DisplayAreaInfo displayAreaInfo, in SurfaceControl leash); void onDisplayAreaVanished(in DisplayAreaInfo displayAreaInfo); void onDisplayAreaInfoChanged(in DisplayAreaInfo displayAreaInfo); } diff --git a/core/java/android/window/ITaskOrganizer.aidl b/core/java/android/window/ITaskOrganizer.aidl index b4f0162b71af..67465252d38e 100644 --- a/core/java/android/window/ITaskOrganizer.aidl +++ b/core/java/android/window/ITaskOrganizer.aidl @@ -25,7 +25,14 @@ import android.window.WindowContainerToken; * {@hide} */ oneway interface ITaskOrganizer { - void onTaskAppeared(in ActivityManager.RunningTaskInfo taskInfo); + /** + * A callback when the Task is available for the registered organizer. The client is responsible + * for releasing the SurfaceControl in the callback. + * + * @param taskInfo The information about the Task that's available + * @param leash A persistent leash for this Task. + */ + void onTaskAppeared(in ActivityManager.RunningTaskInfo taskInfo, in SurfaceControl leash); void onTaskVanished(in ActivityManager.RunningTaskInfo taskInfo); /** diff --git a/core/java/android/window/IWindowContainerToken.aidl b/core/java/android/window/IWindowContainerToken.aidl index 57c7abf9c7e1..81a04e9c10af 100644 --- a/core/java/android/window/IWindowContainerToken.aidl +++ b/core/java/android/window/IWindowContainerToken.aidl @@ -24,9 +24,4 @@ import android.view.SurfaceControl; * @hide */ interface IWindowContainerToken { - - /** - * Gets a persistent leash for this container or {@code null}. - */ - SurfaceControl getLeash(); } diff --git a/core/java/android/window/IWindowOrganizerController.aidl b/core/java/android/window/IWindowOrganizerController.aidl index 7f4b26dba479..7e9c783c83c6 100644 --- a/core/java/android/window/IWindowOrganizerController.aidl +++ b/core/java/android/window/IWindowOrganizerController.aidl @@ -16,9 +16,12 @@ package android.window; +import android.view.SurfaceControl; + import android.window.IDisplayAreaOrganizerController; import android.window.ITaskOrganizerController; import android.window.IWindowContainerTransactionCallback; +import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; /** @hide */ @@ -47,4 +50,15 @@ interface IWindowOrganizerController { /** @return An interface enabling the management of display area organizers. */ IDisplayAreaOrganizerController getDisplayAreaOrganizerController(); + + /** + * Take a screenshot of the requested Window token and place the content of the screenshot into + * outSurfaceControl. The SurfaceControl will be a child of the token's parent, so it will be + * a sibling of the token's window + * @param token The token for the WindowContainer that should get a screenshot taken. + * @param outSurfaceControl The SurfaceControl where the screenshot will be attached. + * + * @return true if the screenshot was successful, false otherwise. + */ + boolean takeScreenshot(in WindowContainerToken token, out SurfaceControl outSurfaceControl); } diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index f661d9af5999..1f5e53369cd8 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -24,6 +24,7 @@ import android.annotation.TestApi; import android.app.ActivityManager; import android.os.RemoteException; import android.util.Singleton; +import android.view.SurfaceControl; import java.util.List; @@ -59,7 +60,8 @@ public class TaskOrganizer extends WindowOrganizer { } @BinderThread - public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} + public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo, + @NonNull SurfaceControl leash) {} @BinderThread public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} @@ -155,8 +157,8 @@ public class TaskOrganizer extends WindowOrganizer { private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() { @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) { - TaskOrganizer.this.onTaskAppeared(taskInfo); + public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { + TaskOrganizer.this.onTaskAppeared(taskInfo, leash); } @Override diff --git a/core/java/android/window/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java index b63741ec69c4..2fb46509f337 100644 --- a/core/java/android/window/TaskOrganizerTaskEmbedder.java +++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java @@ -21,7 +21,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import android.app.ActivityManager; import android.app.ActivityOptions; -import android.app.TaskStackListener; import android.content.Context; import android.graphics.Rect; import android.util.Log; @@ -215,14 +214,14 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { private class TaskOrganizerImpl extends TaskOrganizer { @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) { + public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { if (DEBUG) { log("taskAppeared: " + taskInfo.taskId); } mTaskInfo = taskInfo; mTaskToken = taskInfo.token; - mTaskLeash = mTaskToken.getLeash(); + mTaskLeash = leash; mTransaction.reparent(mTaskLeash, mSurfaceControl) .show(mTaskLeash) .show(mSurfaceControl) diff --git a/core/java/android/window/WindowContainerToken.java b/core/java/android/window/WindowContainerToken.java index 3316d0e5b71f..c92ccae66ff8 100644 --- a/core/java/android/window/WindowContainerToken.java +++ b/core/java/android/window/WindowContainerToken.java @@ -17,14 +17,10 @@ package android.window; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.TestApi; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; -import android.os.RemoteException; -import android.view.SurfaceControl; -import android.window.IWindowContainerToken; /** * Interface for a window container to communicate with the window manager. This also acts as a @@ -45,15 +41,6 @@ public final class WindowContainerToken implements Parcelable { mRealToken = IWindowContainerToken.Stub.asInterface(in.readStrongBinder()); } - @Nullable - public SurfaceControl getLeash() { - try { - return mRealToken.getLeash(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** @hide */ public IBinder asBinder() { return mRealToken.asBinder(); diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java index 457827117f86..ff40ddac134e 100644 --- a/core/java/android/window/WindowOrganizer.java +++ b/core/java/android/window/WindowOrganizer.java @@ -17,11 +17,13 @@ package android.window; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; import android.app.ActivityTaskManager; import android.os.RemoteException; import android.util.Singleton; +import android.view.SurfaceControl; /** * Base class for organizing specific types of windows like Tasks and DisplayAreas @@ -63,6 +65,28 @@ public class WindowOrganizer { } } + /** + * Take a screenshot for a specified Window + * @param token The token for the WindowContainer that should get a screenshot taken. + * @return A SurfaceControl where the screenshot will be attached, or null if failed. + * + * @hide + */ + @Nullable + @RequiresPermission(android.Manifest.permission.READ_FRAME_BUFFER) + public static SurfaceControl takeScreenshot(@NonNull WindowContainerToken token) { + try { + SurfaceControl surfaceControl = new SurfaceControl(); + if (getWindowOrganizerController().takeScreenshot(token, surfaceControl)) { + return surfaceControl; + } else { + return null; + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) static IWindowOrganizerController getWindowOrganizerController() { return IWindowOrganizerControllerSingleton.get(); diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java index 72ebc58380b8..37871d0b5a10 100644 --- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java +++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java @@ -74,7 +74,7 @@ abstract class AccessibilityTarget implements TargetOperations, OnTargetSelected holder.mCheckBoxView.setVisibility(isEditMenuMode ? View.VISIBLE : View.GONE); holder.mIconView.setImageDrawable(getIcon()); holder.mLabelView.setText(getLabel()); - holder.mSwitchItem.setVisibility(View.GONE); + holder.mStatusView.setVisibility(View.GONE); } @Override diff --git a/core/java/com/android/internal/accessibility/dialog/ShortcutTargetAdapter.java b/core/java/com/android/internal/accessibility/dialog/ShortcutTargetAdapter.java index b7605b7fc011..88e18db8da08 100644 --- a/core/java/com/android/internal/accessibility/dialog/ShortcutTargetAdapter.java +++ b/core/java/com/android/internal/accessibility/dialog/ShortcutTargetAdapter.java @@ -68,8 +68,8 @@ class ShortcutTargetAdapter extends TargetAdapter { holder.mIconView = convertView.findViewById(R.id.accessibility_shortcut_target_icon); holder.mLabelView = convertView.findViewById( R.id.accessibility_shortcut_target_label); - holder.mSwitchItem = convertView.findViewById( - R.id.accessibility_shortcut_target_switch_item); + holder.mStatusView = convertView.findViewById( + R.id.accessibility_shortcut_target_status); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); diff --git a/core/java/com/android/internal/accessibility/dialog/TargetAdapter.java b/core/java/com/android/internal/accessibility/dialog/TargetAdapter.java index 1efa17e520ae..28ac9210ac0d 100644 --- a/core/java/com/android/internal/accessibility/dialog/TargetAdapter.java +++ b/core/java/com/android/internal/accessibility/dialog/TargetAdapter.java @@ -19,7 +19,6 @@ package com.android.internal.accessibility.dialog; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.ImageView; -import android.widget.Switch; import android.widget.TextView; /** @@ -30,6 +29,6 @@ abstract class TargetAdapter extends BaseAdapter { CheckBox mCheckBoxView; ImageView mIconView; TextView mLabelView; - Switch mSwitchItem; + TextView mStatusView; } } diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java index 3a42f7e0edb8..239e531dbfb8 100644 --- a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java +++ b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java @@ -24,6 +24,7 @@ import android.content.Context; import android.view.View; import android.view.accessibility.AccessibilityManager.ShortcutType; +import com.android.internal.R; import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType; import com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode; import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder; @@ -49,7 +50,11 @@ class ToggleAccessibilityServiceTarget extends AccessibilityServiceTarget { final boolean isEditMenuMode = shortcutMenuMode == ShortcutMenuMode.EDIT; - holder.mSwitchItem.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE); - holder.mSwitchItem.setChecked(isAccessibilityServiceEnabled(getContext(), getId())); + holder.mStatusView.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE); + + final int statusResId = isAccessibilityServiceEnabled(getContext(), getId()) + ? R.string.accessibility_shortcut_menu_item_status_on + : R.string.accessibility_shortcut_menu_item_status_off; + holder.mStatusView.setText(getContext().getString(statusResId)); } } diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleWhiteListingFeatureTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleWhiteListingFeatureTarget.java index fcbf5eccbd9e..5ab9eb84f0e4 100644 --- a/core/java/com/android/internal/accessibility/dialog/ToggleWhiteListingFeatureTarget.java +++ b/core/java/com/android/internal/accessibility/dialog/ToggleWhiteListingFeatureTarget.java @@ -23,6 +23,7 @@ import android.provider.Settings; import android.view.View; import android.view.accessibility.AccessibilityManager.ShortcutType; +import com.android.internal.R; import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType; import com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode; import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder; @@ -46,8 +47,12 @@ class ToggleWhiteListingFeatureTarget extends AccessibilityTarget { final boolean isEditMenuMode = shortcutMenuMode == ShortcutMenuMode.EDIT; - holder.mSwitchItem.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE); - holder.mSwitchItem.setChecked(isFeatureEnabled()); + holder.mStatusView.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE); + + final int statusResId = isFeatureEnabled() + ? R.string.accessibility_shortcut_menu_item_status_on + : R.string.accessibility_shortcut_menu_item_status_off; + holder.mStatusView.setText(getContext().getString(statusResId)); } private boolean isFeatureEnabled() { diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index b58dbddab44f..a47ad737c2ab 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -301,7 +301,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) { if (shouldShowNoCrossProfileIntentsEmptyState(activeListAdapter)) { - activeListAdapter.postListReadyRunnable(doPostProcessing); + activeListAdapter.postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true); return false; } return activeListAdapter.rebuildList(doPostProcessing); @@ -437,6 +437,9 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { resetViewVisibilitiesForWorkProfileEmptyState(emptyStateView); emptyStateView.setVisibility(View.VISIBLE); + View container = emptyStateView.findViewById(R.id.resolver_empty_state_container); + setupContainerPadding(container); + TextView title = emptyStateView.findViewById(R.id.resolver_empty_state_title); title.setText(titleRes); @@ -463,6 +466,12 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { activeListAdapter.markTabLoaded(); } + /** + * Sets up the padding of the view containing the empty state screens. + * <p>This method is meant to be overridden so that subclasses can customize the padding. + */ + protected void setupContainerPadding(View container) {} + private void showConsumerUserNoAppsAvailableEmptyState(ResolverListAdapter activeListAdapter) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); @@ -555,12 +564,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { } } - /** - * Callback called when the button layout has been hidden. - * <p>This method is meant to be overridden by subclasses. - */ - protected void onButtonLayoutHidden() { } - public interface OnProfileSelectedListener { /** * Callback for when the user changes the active tab from personal to work or vice versa. diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java index def11379bdd6..986614c0963c 100644 --- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java +++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java @@ -53,6 +53,7 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator private final AppPredictor mAppPredictor; private final Context mContext; private final Map<ComponentName, Integer> mTargetRanks = new HashMap<>(); + private final Map<ComponentName, Integer> mTargetScores = new HashMap<>(); private final UserHandle mUser; private final Intent mIntent; private final String mReferrerPackage; @@ -138,6 +139,11 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator // Null value is okay if we have defaulted to the ResolverRankerService. if (msg.what == RANKER_SERVICE_RESULT && msg.obj != null) { final List<AppTarget> sortedAppTargets = (List<AppTarget>) msg.obj; + if (checkAppTargetRankValid(sortedAppTargets)) { + sortedAppTargets.forEach(target -> mTargetScores.put( + new ComponentName(target.getPackageName(), target.getClassName()), + target.getRank())); + } for (int i = 0; i < sortedAppTargets.size(); i++) { mTargetRanks.put(new ComponentName(sortedAppTargets.get(i).getPackageName(), sortedAppTargets.get(i).getClassName()), i); @@ -147,11 +153,23 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator } } + private boolean checkAppTargetRankValid(List<AppTarget> sortedAppTargets) { + for (AppTarget target : sortedAppTargets) { + if (target.getRank() != 0) { + return true; + } + } + return false; + } + @Override float getScore(ComponentName name) { if (mResolverRankerService != null) { return mResolverRankerService.getScore(name); } + if (!mTargetScores.isEmpty()) { + return mTargetScores.get(name); + } Integer rank = mTargetRanks.get(name); if (rank == null) { Log.w(TAG, "Score requested for unknown component."); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index b671fa74bf9a..a144ffb57a15 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -855,10 +855,11 @@ public class ChooserActivity extends ResolverActivity implements Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { + int selectedProfile = findSelectedProfile(); ChooserGridAdapter personalAdapter = createChooserGridAdapter( /* context */ this, /* payloadIntents */ mIntents, - initialIntents, + selectedProfile == PROFILE_PERSONAL ? initialIntents : null, rList, filterLastUsed, mUseLayoutForBrowsables, @@ -866,12 +867,11 @@ public class ChooserActivity extends ResolverActivity implements ChooserGridAdapter workAdapter = createChooserGridAdapter( /* context */ this, /* payloadIntents */ mIntents, - initialIntents, + selectedProfile == PROFILE_WORK ? initialIntents : null, rList, filterLastUsed, mUseLayoutForBrowsables, /* userHandle */ getWorkProfileUserHandle()); - int selectedProfile = findSelectedProfile(); return new ChooserMultiProfilePagerAdapter( /* context */ this, personalAdapter, @@ -2404,10 +2404,9 @@ public class ChooserActivity extends ResolverActivity implements public ChooserGridAdapter createChooserGridAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, boolean useLayoutForBrowsables, UserHandle userHandle) { - ChooserListAdapter chooserListAdapter = new ChooserListAdapter(context, payloadIntents, - initialIntents, rList, - filterLastUsed, createListController(userHandle), useLayoutForBrowsables, - this, this); + ChooserListAdapter chooserListAdapter = createChooserListAdapter(context, payloadIntents, + initialIntents, rList, filterLastUsed, + useLayoutForBrowsables, createListController(userHandle)); AppPredictor.Callback appPredictorCallback = createAppPredictorCallback(chooserListAdapter); AppPredictor appPredictor = setupAppPredictorForUser(userHandle, appPredictorCallback); chooserListAdapter.setAppPredictor(appPredictor); @@ -2416,6 +2415,16 @@ public class ChooserActivity extends ResolverActivity implements } @VisibleForTesting + public ChooserListAdapter createChooserListAdapter(Context context, + List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, + boolean filterLastUsed, boolean useLayoutForBrowsables, + ResolverListController resolverListController) { + return new ChooserListAdapter(context, payloadIntents, initialIntents, rList, + filterLastUsed, resolverListController, useLayoutForBrowsables, + this, this, context.getPackageManager()); + } + + @VisibleForTesting protected ResolverListController createListController(UserHandle userHandle) { AppPredictor appPredictor = getAppPredictorForShareActivitiesIfEnabled(userHandle); AbstractResolverComparator resolverComparator; diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java index bdfcda520281..73ee2950c481 100644 --- a/core/java/com/android/internal/app/ChooserListAdapter.java +++ b/core/java/com/android/internal/app/ChooserListAdapter.java @@ -88,7 +88,7 @@ public class ChooserListAdapter extends ResolverListAdapter { private final int mMaxShortcutTargetsPerApp; private final ChooserListCommunicator mChooserListCommunicator; private final SelectableTargetInfo.SelectableTargetInfoCommunicator - mSelectableTargetInfoComunicator; + mSelectableTargetInfoCommunicator; private int mNumShortcutResults = 0; @@ -117,7 +117,8 @@ public class ChooserListAdapter extends ResolverListAdapter { boolean filterLastUsed, ResolverListController resolverListController, boolean useLayoutForBrowsables, ChooserListCommunicator chooserListCommunicator, - SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoComunicator) { + SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoCommunicator, + PackageManager packageManager) { // Don't send the initial intents through the shared ResolverActivity path, // we want to separate them into a different section. super(context, payloadIntents, null, rList, filterLastUsed, @@ -128,10 +129,9 @@ public class ChooserListAdapter extends ResolverListAdapter { mMaxShortcutTargetsPerApp = context.getResources().getInteger(R.integer.config_maxShortcutTargetsPerApp); mChooserListCommunicator = chooserListCommunicator; - mSelectableTargetInfoComunicator = selectableTargetInfoComunicator; + mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator; if (initialIntents != null) { - final PackageManager pm = context.getPackageManager(); for (int i = 0; i < initialIntents.length; i++) { final Intent ii = initialIntents[i]; if (ii == null) { @@ -147,7 +147,7 @@ public class ChooserListAdapter extends ResolverListAdapter { final ComponentName cn = ii.getComponent(); if (cn != null) { try { - ai = pm.getActivityInfo(ii.getComponent(), 0); + ai = packageManager.getActivityInfo(ii.getComponent(), 0); ri = new ResolveInfo(); ri.activityInfo = ai; } catch (PackageManager.NameNotFoundException ignored) { @@ -155,7 +155,7 @@ public class ChooserListAdapter extends ResolverListAdapter { } } if (ai == null) { - ri = pm.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY); + ri = packageManager.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY); ai = ri != null ? ri.activityInfo : null; } if (ai == null) { @@ -207,9 +207,6 @@ public class ChooserListAdapter extends ResolverListAdapter { if (mListViewDataChanged) { if (mAppendDirectShareEnabled) { appendServiceTargetsWithQuota(); - if (mPendingChooserTargetService.isEmpty()) { - fillAllServiceTargets(); - } } super.notifyDataSetChanged(); } @@ -458,7 +455,7 @@ public class ChooserListAdapter extends ResolverListAdapter { UserHandle userHandle = getUserHandle(); Context contextAsUser = mContext.createContextAsUser(userHandle, 0 /* flags */); boolean isInserted = insertServiceTarget(new SelectableTargetInfo(contextAsUser, - origTarget, target, targetScore, mSelectableTargetInfoComunicator, + origTarget, target, targetScore, mSelectableTargetInfoCommunicator, (isShortcutResult ? directShareToShortcutInfos.get(target) : null))); if (isInserted && isShortcutResult) { @@ -493,6 +490,8 @@ public class ChooserListAdapter extends ResolverListAdapter { pendingChooserTargetServiceConnections) { ComponentName origComponentName = origTarget != null ? origTarget.getResolvedComponentName() : !targets.isEmpty() ? targets.get(0).getComponentName() : null; + Log.i(TAG, + "parkTargetIntoMemory " + origComponentName + ", " + targets.size() + " targets"); mPendingChooserTargetService = pendingChooserTargetServiceConnections.stream() .map(ChooserActivity.ChooserTargetServiceConnection::getComponentName) .filter(componentName -> !componentName.equals(origComponentName)) @@ -508,7 +507,7 @@ public class ChooserListAdapter extends ResolverListAdapter { .map(target -> new SelectableTargetInfo( contextAsUser, origTarget, target, target.getScore(), - mSelectableTargetInfoComunicator, + mSelectableTargetInfoCommunicator, (isShortcutResult ? directShareToShortcutInfos.get(target) : null)) ) @@ -532,32 +531,56 @@ public class ChooserListAdapter extends ResolverListAdapter { private void appendServiceTargetsWithQuota() { int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets(); List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets); - int appRank = 0; + float totalScore = 0f; + for (ComponentName component : topComponentNames) { + if (!mPendingChooserTargetService.contains(component) + && !mParkingDirectShareTargets.containsKey(component)) { + continue; + } + totalScore += super.getScore(component); + } + boolean shouldWaitPendingService = false; for (ComponentName component : topComponentNames) { if (!mPendingChooserTargetService.contains(component) && !mParkingDirectShareTargets.containsKey(component)) { continue; } - appRank++; + float score = super.getScore(component); + int quota = Math.round(maxRankedTargets * score / totalScore); + if (mPendingChooserTargetService.contains(component) && quota >= 1) { + shouldWaitPendingService = true; + } + if (!mParkingDirectShareTargets.containsKey(component)) { + continue; + } + // Append targets into direct share row as per quota. Pair<List<ChooserTargetInfo>, Integer> parkingTargetsItem = mParkingDirectShareTargets.get(component); - if (parkingTargetsItem != null && parkingTargetsItem.second == 0) { - List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first; - int initTargetsQuota = appRank <= maxRankedTargets / 2 ? 2 : 1; - int insertedNum = 0; - while (insertedNum < initTargetsQuota && !parkingTargets.isEmpty()) { - if (!checkDuplicateTarget(parkingTargets.get(0))) { - mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0)); - mValidServiceTargetsNum++; - insertedNum++; - } - parkingTargets.remove(0); - } - mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum)); - if (mShortcutComponents.contains(component)) { - mNumShortcutResults += insertedNum; + List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first; + int insertedNum = parkingTargetsItem.second; + while (insertedNum < quota && !parkingTargets.isEmpty()) { + if (!checkDuplicateTarget(parkingTargets.get(0))) { + mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0)); + mValidServiceTargetsNum++; + insertedNum++; } + parkingTargets.remove(0); + } + Log.i(TAG, " appendServiceTargetsWithQuota component=" + component + + " appendNum=" + (insertedNum - parkingTargetsItem.second)); + if (DEBUG) { + Log.d(TAG, " appendServiceTargetsWithQuota component=" + component + + " score=" + score + + " totalScore=" + totalScore + + " quota=" + quota); + } + if (mShortcutComponents.contains(component)) { + mNumShortcutResults += insertedNum - parkingTargetsItem.second; } + mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum)); + } + if (!shouldWaitPendingService) { + fillAllServiceTargets(); } } @@ -568,6 +591,7 @@ public class ChooserListAdapter extends ResolverListAdapter { if (mParkingDirectShareTargets.isEmpty()) { return; } + Log.i(TAG, " fillAllServiceTargets"); int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets(); List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets); // Append all remaining targets of top recommended components into direct share row. @@ -581,7 +605,8 @@ public class ChooserListAdapter extends ResolverListAdapter { if (mShortcutComponents.contains(component)) { mNumShortcutResults++; } - mServiceTargets.add(target); + mServiceTargets.add(mValidServiceTargetsNum, target); + mValidServiceTargetsNum++; }); mParkingDirectShareTargets.remove(component); } @@ -593,7 +618,8 @@ public class ChooserListAdapter extends ResolverListAdapter { .forEach(targets -> { for (ChooserTargetInfo target : targets) { if (!checkDuplicateTarget(target)) { - mServiceTargets.add(target); + mServiceTargets.add(mValidServiceTargetsNum, target); + mValidServiceTargetsNum++; mNumShortcutResults++; } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 84c833ea5ffe..2f62f8e7a0c9 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -459,13 +459,25 @@ public class ResolverActivity extends Activity implements Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { + // In the edge case when we have 0 apps in the current profile and >1 apps in the other, + // the intent resolver is started in the other profile. Since this is the only case when + // this happens, we check for it here and set the current profile's tab. + int selectedProfile = getCurrentProfile(); + UserHandle intentUser = UserHandle.of(getLaunchingUserId()); + if (!getUser().equals(intentUser)) { + if (getPersonalProfileUserHandle().equals(intentUser)) { + selectedProfile = PROFILE_PERSONAL; + } else if (getWorkProfileUserHandle().equals(intentUser)) { + selectedProfile = PROFILE_WORK; + } + } // We only show the default app for the profile of the current user. The filterLastUsed // flag determines whether to show a default app and that app is not shown in the // resolver list. So filterLastUsed should be false for the other profile. ResolverListAdapter personalAdapter = createResolverListAdapter( /* context */ this, /* payloadIntents */ mIntents, - initialIntents, + selectedProfile == PROFILE_PERSONAL ? initialIntents : null, rList, (filterLastUsed && UserHandle.myUserId() == getPersonalProfileUserHandle().getIdentifier()), @@ -475,24 +487,12 @@ public class ResolverActivity extends Activity implements ResolverListAdapter workAdapter = createResolverListAdapter( /* context */ this, /* payloadIntents */ mIntents, - initialIntents, + selectedProfile == PROFILE_WORK ? initialIntents : null, rList, (filterLastUsed && UserHandle.myUserId() == workProfileUserHandle.getIdentifier()), mUseLayoutForBrowsables, /* userHandle */ workProfileUserHandle); - // In the edge case when we have 0 apps in the current profile and >1 apps in the other, - // the intent resolver is started in the other profile. Since this is the only case when - // this happens, we check for it here and set the current profile's tab. - int selectedProfile = getCurrentProfile(); - UserHandle intentUser = UserHandle.of(getLaunchingUserId()); - if (!getUser().equals(intentUser)) { - if (getPersonalProfileUserHandle().equals(intentUser)) { - selectedProfile = PROFILE_PERSONAL; - } else if (getWorkProfileUserHandle().equals(intentUser)) { - selectedProfile = PROFILE_WORK; - } - } return new ResolverMultiProfilePagerAdapter( /* context */ this, personalAdapter, @@ -1026,10 +1026,15 @@ public class ResolverActivity extends Activity implements } @Override // ResolverListCommunicator - public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing) { + public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing, + boolean rebuildCompleted) { if (isAutolaunching()) { return; } + if (isIntentPicker()) { + ((ResolverMultiProfilePagerAdapter) mMultiProfilePagerAdapter) + .setUseLayoutWithDefault(useLayoutWithDefault()); + } if (mMultiProfilePagerAdapter.shouldShowEmptyStateScreen(listAdapter)) { mMultiProfilePagerAdapter.showEmptyResolverListEmptyState(listAdapter); } else { @@ -1037,7 +1042,7 @@ public class ResolverActivity extends Activity implements } // showEmptyResolverListEmptyState can mark the tab as loaded, // which is a precondition for auto launching - if (maybeAutolaunchActivity()) { + if (rebuildCompleted && maybeAutolaunchActivity()) { return; } if (doPostProcessing) { @@ -1782,13 +1787,14 @@ public class ResolverActivity extends Activity implements if (buttonBarDivider != null) { buttonBarDivider.setVisibility(View.INVISIBLE); } - mMultiProfilePagerAdapter.onButtonLayoutHidden(); + setButtonBarIgnoreOffset(/* ignoreOffset */ false); return; } if (buttonBarDivider != null) { buttonBarDivider.setVisibility(View.VISIBLE); } buttonLayout.setVisibility(View.VISIBLE); + setButtonBarIgnoreOffset(/* ignoreOffset */ true); if (!useLayoutWithDefault()) { int inset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0; @@ -1802,6 +1808,21 @@ public class ResolverActivity extends Activity implements resetAlwaysOrOnceButtonBar(); } + /** + * Updates the button bar container {@code ignoreOffset} layout param. + * <p>Setting this to {@code true} means that the button bar will be glued to the bottom of + * the screen. + */ + private void setButtonBarIgnoreOffset(boolean ignoreOffset) { + View buttonBarContainer = findViewById(R.id.button_bar_container); + if (buttonBarContainer != null) { + ResolverDrawerLayout.LayoutParams layoutParams = + (ResolverDrawerLayout.LayoutParams) buttonBarContainer.getLayoutParams(); + layoutParams.ignoreOffset = ignoreOffset; + buttonBarContainer.setLayoutParams(layoutParams); + } + } + private void resetAlwaysOrOnceButtonBar() { // Disable both buttons initially setAlwaysButtonEnabled(false, ListView.INVALID_POSITION, false); diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java index cee8a923e198..2fd938f45291 100644 --- a/core/java/com/android/internal/app/ResolverListAdapter.java +++ b/core/java/com/android/internal/app/ResolverListAdapter.java @@ -154,6 +154,13 @@ public class ResolverListAdapter extends BaseAdapter { } /** + * Returns the app share score of the given {@code componentName}. + */ + public float getScore(ComponentName componentName) { + return mResolverListController.getScore(componentName); + } + + /** * Returns the list of top K component names which have highest * {@link #getScore(DisplayResolveInfo)} */ @@ -275,7 +282,7 @@ public class ResolverListAdapter extends BaseAdapter { } setPlaceholderCount(placeholderCount); createSortingTask(doPostProcessing).execute(currentResolveList); - postListReadyRunnable(doPostProcessing); + postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ false); return false; } else { processSortedList(currentResolveList, doPostProcessing); @@ -363,7 +370,7 @@ public class ResolverListAdapter extends BaseAdapter { } mResolverListCommunicator.sendVoiceChoicesIfNeeded(); - postListReadyRunnable(doPostProcessing); + postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true); mIsTabLoaded = true; } @@ -373,14 +380,15 @@ public class ResolverListAdapter extends BaseAdapter { * handler thread to update after the current task is finished. * @param doPostProcessing Whether to update the UI and load additional direct share targets * after the list has been rebuilt + * @param rebuildCompleted Whether the list has been completely rebuilt */ - void postListReadyRunnable(boolean doPostProcessing) { + void postListReadyRunnable(boolean doPostProcessing, boolean rebuildCompleted) { if (mPostListReadyRunnable == null) { mPostListReadyRunnable = new Runnable() { @Override public void run() { mResolverListCommunicator.onPostListReady(ResolverListAdapter.this, - doPostProcessing); + doPostProcessing, rebuildCompleted); mPostListReadyRunnable = null; } }; @@ -642,7 +650,8 @@ public class ResolverListAdapter extends BaseAdapter { Intent getReplacementIntent(ActivityInfo activityInfo, Intent defIntent); - void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi); + void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi, + boolean rebuildCompleted); void sendVoiceChoicesIfNeeded(); diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 033ac72dda4e..2b59907cf86b 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -378,6 +378,13 @@ public class ResolverListController { } /** + * Returns the app share score of the given {@code componentName}. + */ + public float getScore(ComponentName componentName) { + return mResolverComparator.getScore(componentName); + } + + /** * Returns the list of top K component names which have highest * {@link #getScore(DisplayResolveInfo)} */ diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java index 5e2470ed9651..b4f9f08e3771 100644 --- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java @@ -36,6 +36,7 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA private final ResolverProfileDescriptor[] mItems; private final boolean mShouldShowNoCrossProfileIntentsEmptyState; + private boolean mUseLayoutWithDefault; ResolverMultiProfilePagerAdapter(Context context, ResolverListAdapter adapter, @@ -213,13 +214,15 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA /* subtitleRes */ 0); } + void setUseLayoutWithDefault(boolean useLayoutWithDefault) { + mUseLayoutWithDefault = useLayoutWithDefault; + } + @Override - protected void onButtonLayoutHidden() { - View emptyStateContainer = getItem(getCurrentPage()).getEmptyStateView() - .findViewById(R.id.resolver_empty_state_container); - emptyStateContainer.setPadding(emptyStateContainer.getPaddingLeft(), - emptyStateContainer.getPaddingTop(), emptyStateContainer.getPaddingRight(), - /* bottom */ 0); + protected void setupContainerPadding(View container) { + int bottom = mUseLayoutWithDefault ? container.getPaddingBottom() : 0; + container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), + container.getPaddingRight(), bottom); } class ResolverProfileDescriptor extends ProfileDescriptor { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 64324756796a..415e21062aa5 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -4009,6 +4009,11 @@ public class BatteryStatsImpl extends BatteryStats { // Otherwise the parent's process state will get downgraded incorrectly return; } + // TODO(b/155216561): It is possible for isolated uids to be in a higher + // state than its parent uid. We should track the highest state within the union of host + // and isolated uids rather than only the parent uid. + FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, + ActivityManager.processStateAmToProto(state)); getUidStatsLocked(uid).updateUidProcessStateLocked(state); } diff --git a/core/java/com/android/internal/policy/DecorContext.java b/core/java/com/android/internal/policy/DecorContext.java index 99b4b5fb7707..51b41198e272 100644 --- a/core/java/com/android/internal/policy/DecorContext.java +++ b/core/java/com/android/internal/policy/DecorContext.java @@ -22,8 +22,6 @@ import android.content.Context; import android.content.res.AssetManager; import android.content.res.Resources; import android.view.ContextThemeWrapper; -import android.view.WindowManager; -import android.view.WindowManagerImpl; import android.view.contentcapture.ContentCaptureManager; import com.android.internal.annotations.VisibleForTesting; @@ -31,8 +29,8 @@ import com.android.internal.annotations.VisibleForTesting; import java.lang.ref.WeakReference; /** - * Context for decor views which can be seeded with pure application context and not depend on the - * activity, but still provide some of the facilities that Activity has, + * Context for decor views which can be seeded with display context and not depend on the activity, + * but still provide some of the facilities that Activity has, * e.g. themes, activity-based resources, etc. * * @hide @@ -40,80 +38,93 @@ import java.lang.ref.WeakReference; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public class DecorContext extends ContextThemeWrapper { private PhoneWindow mPhoneWindow; - private WindowManager mWindowManager; - private Resources mActivityResources; + private Resources mResources; private ContentCaptureManager mContentCaptureManager; - private WeakReference<Context> mActivityContext; + private WeakReference<Context> mContext; - // TODO(b/149928768): Non-activity context can be passed. @VisibleForTesting - public DecorContext(Context context, Context activityContext) { - super(context.createDisplayContext(activityContext.getDisplayNoVerify()), null); - mActivityContext = new WeakReference<>(activityContext); - mActivityResources = activityContext.getResources(); + public DecorContext(Context baseContext, PhoneWindow phoneWindow) { + super(null /* base */, null); + setPhoneWindow(phoneWindow); + final Context displayContext = baseContext.createDisplayContext( + // TODO(b/149790106): Non-activity context can be passed. + phoneWindow.getContext().getDisplayNoVerify()); + attachBaseContext(displayContext); } void setPhoneWindow(PhoneWindow phoneWindow) { mPhoneWindow = phoneWindow; - mWindowManager = null; + final Context context = phoneWindow.getContext(); + mContext = new WeakReference<>(context); + mResources = context.getResources(); } @Override public Object getSystemService(String name) { if (Context.WINDOW_SERVICE.equals(name)) { - if (mWindowManager == null) { - WindowManagerImpl wm = - (WindowManagerImpl) super.getSystemService(Context.WINDOW_SERVICE); - mWindowManager = wm.createLocalWindowManager(mPhoneWindow); - } - return mWindowManager; + return mPhoneWindow.getWindowManager(); } + final Context context = mContext.get(); if (Context.CONTENT_CAPTURE_MANAGER_SERVICE.equals(name)) { - if (mContentCaptureManager == null) { - Context activityContext = mActivityContext.get(); - if (activityContext != null) { - mContentCaptureManager = (ContentCaptureManager) activityContext - .getSystemService(name); - } + if (context != null && mContentCaptureManager == null) { + mContentCaptureManager = (ContentCaptureManager) context.getSystemService(name); } return mContentCaptureManager; } - return super.getSystemService(name); + // TODO(b/154191411): Try to revisit this issue in S. + // We use application to get DisplayManager here because ViewRootImpl holds reference of + // DisplayManager and implicitly holds reference of mContext, which makes activity cannot + // be GC'd even after destroyed if mContext is an activity object. + if (Context.DISPLAY_SERVICE.equals(name)) { + return super.getSystemService(name); + } + // LayoutInflater and WallpaperManagerService should also be obtained from visual context + // instead of base context. + return (context != null) ? context.getSystemService(name) : super.getSystemService(name); } @Override public Resources getResources() { - Context activityContext = mActivityContext.get(); + Context context = mContext.get(); // Attempt to update the local cached Resources from the activity context. If the activity // is no longer around, return the old cached values. - if (activityContext != null) { - mActivityResources = activityContext.getResources(); + if (context != null) { + mResources = context.getResources(); } - return mActivityResources; + return mResources; } @Override public AssetManager getAssets() { - return mActivityResources.getAssets(); + return mResources.getAssets(); } @Override public AutofillOptions getAutofillOptions() { - Context activityContext = mActivityContext.get(); - if (activityContext != null) { - return activityContext.getAutofillOptions(); + Context context = mContext.get(); + if (context != null) { + return context.getAutofillOptions(); } return null; } @Override public ContentCaptureOptions getContentCaptureOptions() { - Context activityContext = mActivityContext.get(); - if (activityContext != null) { - return activityContext.getContentCaptureOptions(); + Context context = mContext.get(); + if (context != null) { + return context.getContentCaptureOptions(); } return null; } + + @Override + public boolean isUiContext() { + Context context = mContext.get(); + if (context != null) { + return context.isUiContext(); + } + return false; + } } diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index f5d38ca37bb7..863659d7c4eb 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -2019,10 +2019,17 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind if (getForeground() != null) { drawableChanged(); } - getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight()); } } + /** + * An interface to be called when the caption visibility or height changed, to report the + * corresponding insets change to the InsetsController. + */ + public void notifyCaptionHeightChanged() { + getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight()); + } + void setWindow(PhoneWindow phoneWindow) { mWindow = phoneWindow; Context context = getContext(); @@ -2093,7 +2100,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind mDecorCaptionView.onConfigurationChanged(displayWindowDecor); enableCaption(displayWindowDecor); } - getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight()); } void onResourcesLoaded(LayoutInflater inflater, int layoutResource) { diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 23ba6530b072..aa75d4010748 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -2358,7 +2358,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (applicationContext == null) { context = getContext(); } else { - context = new DecorContext(applicationContext, getContext()); + context = new DecorContext(applicationContext, this); if (mTheme != -1) { context.setTheme(mTheme); } diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index adadc5e20549..49c9302eeb11 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -27,6 +27,9 @@ import java.util.function.Consumer; public class ScreenshotHelper { + public static final int SCREENSHOT_MSG_URI = 1; + public static final int SCREENSHOT_MSG_PROCESS_COMPLETE = 2; + /** * Describes a screenshot request (to make it easier to pass data through to the handler). */ @@ -135,6 +138,7 @@ public class ScreenshotHelper { private final int SCREENSHOT_TIMEOUT_MS = 10000; private final Object mScreenshotLock = new Object(); + private IBinder mScreenshotService = null; private ServiceConnection mScreenshotConnection = null; private final Context mContext; @@ -251,85 +255,104 @@ public class ScreenshotHelper { private void takeScreenshot(final int screenshotType, long timeoutMs, @NonNull Handler handler, ScreenshotRequest screenshotRequest, @Nullable Consumer<Uri> completionConsumer) { synchronized (mScreenshotLock) { - if (mScreenshotConnection != null) { - return; - } - final ComponentName serviceComponent = ComponentName.unflattenFromString( - mContext.getResources().getString( - com.android.internal.R.string.config_screenshotServiceComponent)); - final Intent serviceIntent = new Intent(); - final Runnable mScreenshotTimeout = new Runnable() { - @Override - public void run() { - synchronized (mScreenshotLock) { - if (mScreenshotConnection != null) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; - notifyScreenshotError(); - } - } - if (completionConsumer != null) { - completionConsumer.accept(null); + final Runnable mScreenshotTimeout = () -> { + synchronized (mScreenshotLock) { + if (mScreenshotConnection != null) { + mContext.unbindService(mScreenshotConnection); + mScreenshotConnection = null; + mScreenshotService = null; + notifyScreenshotError(); } } + if (completionConsumer != null) { + completionConsumer.accept(null); + } }; - serviceIntent.setComponent(serviceComponent); - ServiceConnection conn = new ServiceConnection() { + Message msg = Message.obtain(null, screenshotType, screenshotRequest); + final ServiceConnection myConn = mScreenshotConnection; + Handler h = new Handler(handler.getLooper()) { @Override - public void onServiceConnected(ComponentName name, IBinder service) { - synchronized (mScreenshotLock) { - if (mScreenshotConnection != this) { - return; - } - Messenger messenger = new Messenger(service); - Message msg = Message.obtain(null, screenshotType, screenshotRequest); - final ServiceConnection myConn = this; - Handler h = new Handler(handler.getLooper()) { - @Override - public void handleMessage(Message msg) { - synchronized (mScreenshotLock) { - if (mScreenshotConnection == myConn) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; - handler.removeCallbacks(mScreenshotTimeout); - } + public void handleMessage(Message msg) { + switch (msg.what) { + case SCREENSHOT_MSG_URI: + if (completionConsumer != null) { + completionConsumer.accept((Uri) msg.obj); + } + handler.removeCallbacks(mScreenshotTimeout); + break; + case SCREENSHOT_MSG_PROCESS_COMPLETE: + synchronized (mScreenshotLock) { + if (mScreenshotConnection == myConn) { + mContext.unbindService(mScreenshotConnection); + mScreenshotConnection = null; + mScreenshotService = null; } + } + break; + } + } + }; + msg.replyTo = new Messenger(h); + + if (mScreenshotConnection == null) { + final ComponentName serviceComponent = ComponentName.unflattenFromString( + mContext.getResources().getString( + com.android.internal.R.string.config_screenshotServiceComponent)); + final Intent serviceIntent = new Intent(); + + serviceIntent.setComponent(serviceComponent); + ServiceConnection conn = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + synchronized (mScreenshotLock) { + if (mScreenshotConnection != this) { + return; + } + mScreenshotService = service; + Messenger messenger = new Messenger(mScreenshotService); + + try { + messenger.send(msg); + } catch (RemoteException e) { + Log.e(TAG, "Couldn't take screenshot: " + e); if (completionConsumer != null) { - completionConsumer.accept((Uri) msg.obj); + completionConsumer.accept(null); } } - }; - msg.replyTo = new Messenger(h); + } + } - try { - messenger.send(msg); - } catch (RemoteException e) { - Log.e(TAG, "Couldn't take screenshot: " + e); - if (completionConsumer != null) { - completionConsumer.accept(null); + @Override + public void onServiceDisconnected(ComponentName name) { + synchronized (mScreenshotLock) { + if (mScreenshotConnection != null) { + mContext.unbindService(mScreenshotConnection); + mScreenshotConnection = null; + mScreenshotService = null; + handler.removeCallbacks(mScreenshotTimeout); + notifyScreenshotError(); } } } + }; + if (mContext.bindServiceAsUser(serviceIntent, conn, + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, + UserHandle.CURRENT)) { + mScreenshotConnection = conn; + handler.postDelayed(mScreenshotTimeout, timeoutMs); } - - @Override - public void onServiceDisconnected(ComponentName name) { - synchronized (mScreenshotLock) { - if (mScreenshotConnection != null) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; - handler.removeCallbacks(mScreenshotTimeout); - notifyScreenshotError(); - } + } else { + Messenger messenger = new Messenger(mScreenshotService); + try { + messenger.send(msg); + } catch (RemoteException e) { + Log.e(TAG, "Couldn't take screenshot: " + e); + if (completionConsumer != null) { + completionConsumer.accept(null); } } - }; - if (mContext.bindServiceAsUser(serviceIntent, conn, - Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, - UserHandle.CURRENT)) { - mScreenshotConnection = conn; handler.postDelayed(mScreenshotTimeout, timeoutMs); } } diff --git a/core/java/com/android/internal/view/inline/IInlineContentCallback.aidl b/core/java/com/android/internal/view/inline/IInlineContentCallback.aidl index feb3f026b806..64f7fa77e485 100644 --- a/core/java/com/android/internal/view/inline/IInlineContentCallback.aidl +++ b/core/java/com/android/internal/view/inline/IInlineContentCallback.aidl @@ -23,7 +23,7 @@ import android.view.SurfaceControlViewHost; * {@hide} */ oneway interface IInlineContentCallback { - void onContent(in SurfaceControlViewHost.SurfacePackage content); + void onContent(in SurfaceControlViewHost.SurfacePackage content, int width, int height); void onClick(); void onLongClick(); } diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java index 26684201019c..688e00bc5a29 100644 --- a/core/java/com/android/internal/widget/ConversationLayout.java +++ b/core/java/com/android/internal/widget/ConversationLayout.java @@ -35,10 +35,14 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.Typeface; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Parcelable; +import android.text.Spannable; +import android.text.SpannableString; import android.text.TextUtils; +import android.text.style.StyleSpan; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.DisplayMetrics; @@ -109,12 +113,11 @@ public class ConversationLayout extends FrameLayout private CharSequence mNameReplacement; private boolean mIsCollapsed; private ImageResolver mImageResolver; - private CachingIconView mConversationIcon; + private CachingIconView mConversationIconView; private View mConversationIconContainer; - private int mConversationIconTopPadding; private int mConversationIconTopPaddingExpandedGroup; - private int mConversationIconTopPaddingNoAppName; - private int mExpandedGroupMessagePaddingNoAppName; + private int mConversationIconTopPadding; + private int mExpandedGroupMessagePadding; private TextView mConversationText; private View mConversationIconBadge; private CachingIconView mConversationIconBadgeBg; @@ -157,6 +160,8 @@ public class ConversationLayout extends FrameLayout private ViewGroup mAppOps; private Rect mAppOpsTouchRect = new Rect(); private float mMinTouchSize; + private Icon mConversationIcon; + private View mAppNameDivider; public ConversationLayout(@NonNull Context context) { super(context); @@ -192,7 +197,7 @@ public class ConversationLayout extends FrameLayout mAvatarSize = getResources().getDimensionPixelSize(R.dimen.messaging_avatar_size); mTextPaint.setTextAlign(Paint.Align.CENTER); mTextPaint.setAntiAlias(true); - mConversationIcon = findViewById(R.id.conversation_icon); + mConversationIconView = findViewById(R.id.conversation_icon); mConversationIconContainer = findViewById(R.id.conversation_icon_container); mIcon = findViewById(R.id.icon); mAppOps = findViewById(com.android.internal.R.id.app_ops); @@ -232,7 +237,7 @@ public class ConversationLayout extends FrameLayout }); // When the conversation icon is gone, hide the whole badge - mConversationIcon.setOnForceHiddenChangedListener((forceHidden) -> { + mConversationIconView.setOnForceHiddenChangedListener((forceHidden) -> { animateViewForceHidden(mConversationIconBadgeBg, forceHidden); animateViewForceHidden(mImportanceRingView, forceHidden); animateViewForceHidden(mIcon, forceHidden); @@ -256,14 +261,12 @@ public class ConversationLayout extends FrameLayout R.dimen.conversation_avatar_size); mConversationAvatarSizeExpanded = getResources().getDimensionPixelSize( R.dimen.conversation_avatar_size_group_expanded); - mConversationIconTopPadding = getResources().getDimensionPixelSize( - R.dimen.conversation_icon_container_top_padding); mConversationIconTopPaddingExpandedGroup = getResources().getDimensionPixelSize( R.dimen.conversation_icon_container_top_padding_small_avatar); - mConversationIconTopPaddingNoAppName = getResources().getDimensionPixelSize( - R.dimen.conversation_icon_container_top_padding_no_app_name); - mExpandedGroupMessagePaddingNoAppName = getResources().getDimensionPixelSize( - R.dimen.expanded_group_conversation_message_padding_without_app_name); + mConversationIconTopPadding = getResources().getDimensionPixelSize( + R.dimen.conversation_icon_container_top_padding); + mExpandedGroupMessagePadding = getResources().getDimensionPixelSize( + R.dimen.expanded_group_conversation_message_padding); mExpandedGroupSideMargin = getResources().getDimensionPixelSize( R.dimen.conversation_badge_side_margin_group_expanded); mExpandedGroupSideMarginFacePile = getResources().getDimensionPixelSize( @@ -282,6 +285,7 @@ public class ConversationLayout extends FrameLayout mFallbackGroupChatName = getResources().getString( R.string.conversation_title_fallback_group_chat); mAppName = findViewById(R.id.app_name_text); + mAppNameDivider = findViewById(R.id.app_name_divider); mAppNameGone = mAppName.getVisibility() == GONE; mAppName.setOnVisibilityChangedListener((visibility) -> { onAppNameVisibilityChanged(); @@ -463,7 +467,7 @@ public class ConversationLayout extends FrameLayout CharSequence conversationText = mConversationTitle; if (mIsOneToOne) { // Let's resolve the icon / text from the last sender - mConversationIcon.setVisibility(VISIBLE); + mConversationIconView.setVisibility(VISIBLE); mConversationFacePile.setVisibility(GONE); CharSequence userKey = getKey(mUser); for (int i = mGroups.size() - 1; i >= 0; i--) { @@ -480,17 +484,20 @@ public class ConversationLayout extends FrameLayout if (avatarIcon == null) { avatarIcon = createAvatarSymbol(conversationText, "", mLayoutColor); } - mConversationIcon.setImageIcon(avatarIcon); + mConversationIcon = avatarIcon; + mConversationIconView.setImageIcon(mConversationIcon); break; } } } else { if (mLargeIcon != null) { - mConversationIcon.setVisibility(VISIBLE); + mConversationIcon = mLargeIcon; + mConversationIconView.setVisibility(VISIBLE); mConversationFacePile.setVisibility(GONE); - mConversationIcon.setImageIcon(mLargeIcon); + mConversationIconView.setImageIcon(mLargeIcon); } else { - mConversationIcon.setVisibility(GONE); + mConversationIcon = null; + mConversationIconView.setVisibility(GONE); // This will also inflate it! mConversationFacePile.setVisibility(VISIBLE); // rebind the value to the inflated view instead of the stub @@ -516,6 +523,7 @@ public class ConversationLayout extends FrameLayout updateImageMessages(); updatePaddingsBasedOnContentAvailability(); updateActionListPadding(); + updateAppNameDividerVisibility(); } private void updateActionListPadding() { @@ -561,15 +569,8 @@ public class ConversationLayout extends FrameLayout mImageMessageContainer.setVisibility(newMessage != null ? VISIBLE : GONE); } - private void bindFacePile() { - // Let's bind the face pile - ImageView bottomBackground = mConversationFacePile.findViewById( - R.id.conversation_face_pile_bottom_background); + public void bindFacePile(ImageView bottomBackground, ImageView bottomView, ImageView topView) { applyNotificationBackgroundColor(bottomBackground); - ImageView bottomView = mConversationFacePile.findViewById( - R.id.conversation_face_pile_bottom); - ImageView topView = mConversationFacePile.findViewById( - R.id.conversation_face_pile_top); // Let's find the two last conversations: Icon secondLastIcon = null; CharSequence lastKey = null; @@ -601,6 +602,17 @@ public class ConversationLayout extends FrameLayout secondLastIcon = createAvatarSymbol("", "", mLayoutColor); } topView.setImageIcon(secondLastIcon); + } + + private void bindFacePile() { + ImageView bottomBackground = mConversationFacePile.findViewById( + R.id.conversation_face_pile_bottom_background); + ImageView bottomView = mConversationFacePile.findViewById( + R.id.conversation_face_pile_bottom); + ImageView topView = mConversationFacePile.findViewById( + R.id.conversation_face_pile_top); + + bindFacePile(bottomBackground, bottomView, topView); int conversationAvatarSize; int facepileAvatarSize; @@ -614,7 +626,7 @@ public class ConversationLayout extends FrameLayout facepileAvatarSize = mFacePileAvatarSizeExpandedGroup; facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidthExpanded; } - LayoutParams layoutParams = (LayoutParams) mConversationIcon.getLayoutParams(); + LayoutParams layoutParams = (LayoutParams) mConversationIconView.getLayoutParams(); layoutParams.width = conversationAvatarSize; layoutParams.height = conversationAvatarSize; mConversationFacePile.setLayoutParams(layoutParams); @@ -664,36 +676,24 @@ public class ConversationLayout extends FrameLayout layoutParams.setMarginStart(sidemargin); mConversationIconBadge.setLayoutParams(layoutParams); - if (mConversationIcon.getVisibility() == VISIBLE) { - layoutParams = (LayoutParams) mConversationIcon.getLayoutParams(); + if (mConversationIconView.getVisibility() == VISIBLE) { + layoutParams = (LayoutParams) mConversationIconView.getLayoutParams(); layoutParams.width = conversationAvatarSize; layoutParams.height = conversationAvatarSize; - mConversationIcon.setLayoutParams(layoutParams); + mConversationIconView.setLayoutParams(layoutParams); } } private void updatePaddingsBasedOnContentAvailability() { - int containerTopPadding; - int messagingPadding = 0; - if (mIsOneToOne || mIsCollapsed) { - containerTopPadding = mConversationIconTopPadding; - } else { - if (mAppName.getVisibility() != GONE) { - // The app name is visible, let's center outselves in the two lines - containerTopPadding = mConversationIconTopPaddingExpandedGroup; - } else { - // App name is gone, let's center ourselves int he one remaining line - containerTopPadding = mConversationIconTopPaddingNoAppName; - - // The app name is gone and we're a group, we'll need to add some extra padding - // to the messages, since otherwise it will overlap with the group - messagingPadding = mExpandedGroupMessagePaddingNoAppName; - } - } + int messagingPadding = mIsOneToOne || mIsCollapsed + ? 0 + // Add some extra padding to the messages, since otherwise it will overlap with the + // group + : mExpandedGroupMessagePadding; mConversationIconContainer.setPaddingRelative( mConversationIconContainer.getPaddingStart(), - containerTopPadding, + mConversationIconTopPadding, mConversationIconContainer.getPaddingEnd(), mConversationIconContainer.getPaddingBottom()); @@ -719,6 +719,10 @@ public class ConversationLayout extends FrameLayout mConversationTitle = conversationTitle; } + public CharSequence getConversationTitle() { + return mConversationText.getText(); + } + private void removeGroups(ArrayList<MessagingGroup> oldGroups) { int size = oldGroups.size(); for (int i = 0; i < size; i++) { @@ -1198,10 +1202,14 @@ public class ConversationLayout extends FrameLayout boolean appNameGone = mAppName.getVisibility() == GONE; if (appNameGone != mAppNameGone) { mAppNameGone = appNameGone; - updatePaddingsBasedOnContentAvailability(); + updateAppNameDividerVisibility(); } } + private void updateAppNameDividerVisibility() { + mAppNameDivider.setVisibility(mAppNameGone ? GONE : VISIBLE); + } + public void updateExpandability(boolean expandable, @Nullable OnClickListener onClickListener) { mExpandable = expandable; if (expandable) { @@ -1218,4 +1226,43 @@ public class ConversationLayout extends FrameLayout public void setMessagingClippingDisabled(boolean clippingDisabled) { mMessagingLinearLayout.setClipBounds(clippingDisabled ? null : mMessagingClipRect); } + + @Nullable + public CharSequence getConversationSenderName() { + if (mGroups.isEmpty()) { + return null; + } + final CharSequence name = mGroups.get(mGroups.size() - 1).getSenderName(); + return getResources().getString(R.string.conversation_single_line_name_display, name); + } + + public boolean isOneToOne() { + return mIsOneToOne; + } + + @Nullable + public CharSequence getConversationText() { + if (mMessages.isEmpty()) { + return null; + } + final MessagingMessage messagingMessage = mMessages.get(mMessages.size() - 1); + final CharSequence text = messagingMessage.getMessage().getText(); + if (text == null && messagingMessage instanceof MessagingImageMessage) { + final String unformatted = + getResources().getString(R.string.conversation_single_line_image_placeholder); + SpannableString spannableString = new SpannableString(unformatted); + spannableString.setSpan( + new StyleSpan(Typeface.ITALIC), + 0, + spannableString.length(), + Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + return spannableString; + } + return text; + } + + @Nullable + public Icon getConversationIcon() { + return mConversationIcon; + } } diff --git a/core/java/com/android/internal/widget/DecorCaptionView.java b/core/java/com/android/internal/widget/DecorCaptionView.java index 7a01024ffc36..21021457377a 100644 --- a/core/java/com/android/internal/widget/DecorCaptionView.java +++ b/core/java/com/android/internal/widget/DecorCaptionView.java @@ -30,6 +30,7 @@ import android.view.ViewOutlineProvider; import android.view.Window; import com.android.internal.R; +import com.android.internal.policy.DecorView; import com.android.internal.policy.PhoneWindow; import java.util.ArrayList; @@ -305,6 +306,8 @@ public class DecorCaptionView extends ViewGroup implements View.OnTouchListener, } } + ((DecorView) mOwner.getDecorView()).notifyCaptionHeightChanged(); + // This assumes that the caption bar is at the top. mOwner.notifyRestrictedCaptionAreaCallback(mMaximize.getLeft(), mMaximize.getTop(), mClose.getRight(), mClose.getBottom()); diff --git a/core/java/com/android/internal/widget/InlinePresentationStyleUtils.java b/core/java/com/android/internal/widget/InlinePresentationStyleUtils.java index db1725ff461c..9c1aa284a02c 100644 --- a/core/java/com/android/internal/widget/InlinePresentationStyleUtils.java +++ b/core/java/com/android/internal/widget/InlinePresentationStyleUtils.java @@ -52,10 +52,10 @@ public final class InlinePresentationStyleUtils { for (String key : keys) { Object value1 = bundle1.get(key); Object value2 = bundle2.get(key); - if (value1 instanceof Bundle && value2 instanceof Bundle - && !bundleEquals((Bundle) value1, (Bundle) value2)) { - return false; - } else if (!Objects.equals(value1, value2)) { + final boolean equal = value1 instanceof Bundle && value2 instanceof Bundle + ? bundleEquals((Bundle) value1, (Bundle) value2) + : Objects.equals(value1, value2); + if (!equal) { return false; } } diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp index 185e58160adf..23f4325c0ff1 100644 --- a/core/jni/android_graphics_BLASTBufferQueue.cpp +++ b/core/jni/android_graphics_BLASTBufferQueue.cpp @@ -29,9 +29,10 @@ namespace android { -static jlong nativeCreate(JNIEnv* env, jclass clazz, jlong surfaceControl, jlong width, jlong height) { +static jlong nativeCreate(JNIEnv* env, jclass clazz, jlong surfaceControl, jlong width, jlong height, + jboolean enableTripleBuffering) { sp<BLASTBufferQueue> queue = new BLASTBufferQueue( - reinterpret_cast<SurfaceControl*>(surfaceControl), width, height); + reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, enableTripleBuffering); queue->incStrong((void*)nativeCreate); return reinterpret_cast<jlong>(queue.get()); } @@ -59,7 +60,7 @@ static void nativeUpdate(JNIEnv*env, jclass clazz, jlong ptr, jlong surfaceContr static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ - { "nativeCreate", "(JJJ)J", + { "nativeCreate", "(JJJZ)J", (void*)nativeCreate }, { "nativeGetSurface", "(J)Landroid/view/Surface;", (void*)nativeGetSurface }, diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index 6cbc5878db61..8d193bfa1dd2 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -307,6 +307,9 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this, status); goto native_init_failure; } + // Set caller name so it can be logged in destructor. + // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_JAVA + lpRecorder->setCallerName("java"); } else { // end if nativeRecordInJavaObj == 0) lpRecorder = (AudioRecord*)nativeRecordInJavaObj; // TODO: We need to find out which members of the Java AudioRecord might need to be diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 13518186376d..5c045b65be22 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -425,6 +425,9 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we ALOGE("Error %d initializing AudioTrack", status); goto native_init_failure; } + // Set caller name so it can be logged in destructor. + // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_JAVA + lpTrack->setCallerName("java"); } else { // end if (nativeAudioTrack == 0) lpTrack = (AudioTrack*)nativeAudioTrack; // TODO: We need to find out which members of the Java AudioTrack might diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index 997829eacf96..bfa5d70663ab 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2678,4 +2678,15 @@ enum PageId { // CATEGORY: SETTINGS // OS: R DEVICE_CONTROLS_SETTINGS = 1844; + + // ACTION: Settings > Wi-Fi > Tap on Openroaming Wi-Fi + // CATEGORY: SETTINGS + // OS: R + OPENROAMING_TAP = 1845; + + // When device already using any Wi-Fi service, to track if user still want to use Openroaming + // ACTION: Settings > Wi-Fi > Tap on Openroaming Wi-Fi + // CATEGORY: SETTINGS + // OS: R + OPENROAMING_TAP_ON_WIFI_CONNECTION = 1846; } diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto index 896ee4fa42a5..7c1a04944d68 100644 --- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto +++ b/core/proto/android/stats/devicepolicy/device_policy_enums.proto @@ -197,4 +197,8 @@ enum EventId { CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED = 170; CROSS_PROFILE_SETTINGS_PAGE_USER_DECLINED_CONSENT = 171; CROSS_PROFILE_SETTINGS_PAGE_PERMISSION_REVOKED = 172; + DOCSUI_EMPTY_STATE_NO_PERMISSION = 173; + DOCSUI_EMPTY_STATE_QUIET_MODE = 174; + DOCSUI_LAUNCH_OTHER_APP = 175; + DOCSUI_PICK_RESULT = 176; } diff --git a/core/res/res/layout/accessibility_shortcut_chooser_item.xml b/core/res/res/layout/accessibility_shortcut_chooser_item.xml index fff22d916b15..7cca1292af68 100644 --- a/core/res/res/layout/accessibility_shortcut_chooser_item.xml +++ b/core/res/res/layout/accessibility_shortcut_chooser_item.xml @@ -49,12 +49,13 @@ android:textColor="?attr/textColorPrimary" android:fontFamily="sans-serif-medium"/> - <Switch - android:id="@+id/accessibility_shortcut_target_switch_item" + <TextView + android:id="@+id/accessibility_shortcut_target_status" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@null" - android:clickable="false" - android:focusable="false"/> + android:textSize="20sp" + android:textColor="?attr/colorAccent" + android:fontFamily="sans-serif-medium"/> + </LinearLayout> diff --git a/core/res/res/layout/conversation_face_pile_layout.xml b/core/res/res/layout/conversation_face_pile_layout.xml index 528562534aab..95c14d7c6b5a 100644 --- a/core/res/res/layout/conversation_face_pile_layout.xml +++ b/core/res/res/layout/conversation_face_pile_layout.xml @@ -12,7 +12,7 @@ ~ 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 + ~ limitations underthe License --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index ece59e2abb22..23b8bd34829e 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -24,12 +24,20 @@ android:layout_height="@dimen/notification_header_height" android:clipChildren="false" style="?attr/notificationHeaderStyle"> - <com.android.internal.widget.CachingIconView - android:id="@+id/icon" - android:layout_width="?attr/notificationHeaderIconSize" - android:layout_height="?attr/notificationHeaderIconSize" - android:layout_marginEnd="@dimen/notification_header_icon_margin_end" + <!-- Wrapper used to expand the width of the "space" containing the icon programmatically --> + <FrameLayout + android:id="@+id/header_icon_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <com.android.internal.widget.CachingIconView + android:id="@+id/icon" + android:layout_width="?attr/notificationHeaderIconSize" + android:layout_height="?attr/notificationHeaderIconSize" + android:layout_marginEnd="@dimen/notification_header_icon_margin_end" + android:layout_gravity="center" /> + </FrameLayout> <TextView android:id="@+id/app_name_text" android:layout_width="wrap_content" diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml index 8a57e057b084..9a9d8b96c677 100644 --- a/core/res/res/layout/notification_template_material_conversation.xml +++ b/core/res/res/layout/notification_template_material_conversation.xml @@ -139,6 +139,33 @@ android:layout_weight="1" /> + + <TextView + android:id="@+id/app_name_divider" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?attr/notificationHeaderTextAppearance" + android:layout_marginStart="@dimen/notification_header_separating_margin" + android:layout_marginEnd="@dimen/notification_header_separating_margin" + android:text="@string/notification_header_divider_symbol" + android:layout_gravity="center" + android:paddingTop="1sp" + android:singleLine="true" + android:visibility="gone" + /> + + <!-- App Name --> + <com.android.internal.widget.ObservableTextView + android:id="@+id/app_name_text" + android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginStart="@dimen/notification_header_separating_margin" + android:paddingTop="1sp" + android:singleLine="true" + /> + <TextView android:id="@+id/time_divider" android:layout_width="wrap_content" @@ -230,17 +257,6 @@ </LinearLayout> </LinearLayout> - <!-- App Name --> - <com.android.internal.widget.ObservableTextView - android:id="@+id/app_name_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="@dimen/conversation_content_start" - android:textSize="12sp" - android:layout_marginBottom="16dp" - android:textAppearance="@style/TextAppearance.DeviceDefault.Notification" - /> - <!-- Messages --> <com.android.internal.widget.MessagingLinearLayout android:id="@+id/notification_messaging" diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml index 76ecefc67c22..4d0837f495df 100644 --- a/core/res/res/layout/resolver_list.xml +++ b/core/res/res/layout/resolver_list.xml @@ -113,11 +113,13 @@ </LinearLayout> </TabHost> <LinearLayout + android:id="@+id/button_bar_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alwaysShow="true" android:orientation="vertical" - android:background="?attr/colorBackgroundFloating"> + android:background="?attr/colorBackgroundFloating" + android:layout_ignoreOffset="true"> <View android:id="@+id/resolver_button_bar_divider" android:layout_width="match_parent" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 9d152aaaa582..7024755dd2d8 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Jou toestel sal uitgevee word"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Die administrasieprogram kan nie gebruik word nie. Jou toestel sal nou uitgevee word.\n\nKontak jou organisasie se administrateur as jy vrae het."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Druk is gedeaktiveer deur <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Deblokkeer jou persoonlike programme"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Programme word môre geblokkeer"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Jou IT-administrateur laat nie toe dat jou werkprofiel vir langer as <xliff:g id="DAYS">%1$d</xliff:g> dae onderbreek word nie"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Skakel jou werkprofiel aan"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Jou persoonlike programme word geblokkeer totdat jy jou werkprofiel aanskakel"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Jou persoonlike programme sal môre geblokkeer word"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Skakel werkprofiel aan"</string> <string name="me" msgid="6207584824693813140">"Ek"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet-opsies"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"As jy albei volumesleutels vir \'n paar sekondes hou, skakel dit <xliff:g id="SERVICE">%1$s</xliff:g>, \'n toeganklikheidkenmerk, aan. Dit kan verander hoe jou toestel werk.\n\nJy kan hierdie kortpad na \'n ander kenmerk in Instellings en Toeganklikheid verander."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Skakel aan"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Moenie aanskakel nie"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AAN"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Gee <xliff:g id="SERVICE">%1$s</xliff:g> volle beheer oor jou toestel?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"As jy <xliff:g id="SERVICE">%1$s</xliff:g> aanskakel, sal jou toestel nie jou skermslot gebruik om data-enkripsie te verbeter nie."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Volle beheer is gepas vir programme wat jou help met toeganklikheidsbehoeftes, maar nie vir die meeste programme nie."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Opgedateer deur jou administrateur"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Uitgevee deur jou administrateur"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Batterybespaarder doen die volgende om die batterylewe te verleng:\n·Skakel Donkertema aan\n·Skakel agtergrondaktiwiteit, sommige visuele effekte en ander kenmerke, soos \"Hey Google\", af of beperk hulle\n\n"<annotation id="url">"Kom meer te wete"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Batterybespaarder doen die volgende om die batterylewe te verleng:\n·Skakel Donkertema aan\n·Skakel agtergrondaktiwiteit, sommige visuele effekte en ander kenmerke, soos \"Hey Google\", af of beperk hulle"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Databespaarder verhoed sommige programme om data in die agtergrond te stuur of te aanvaar om datagebruik te help verminder. \'n Program wat jy tans gebruik kan by data ingaan, maar sal dit dalk minder gereeld doen. Dit kan byvoorbeeld beteken dat prente nie wys totdat jy op hulle tik nie."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Skakel Databespaarder aan?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Skakel aan"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Kennisgewings"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Kitsinstellings"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Kragdialoog"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Wissel verdeelde skerm"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Sluitskerm"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skermkiekie"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Toeganklikheid-kieslys"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> se onderskrifbalk."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in die BEPERK-groep geplaas"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Gesprek"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Groepsgesprek"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index af6e15f57a70..df521e037300 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"የእርስዎ መሣሪያ ይደመሰሳል"</string> <string name="factory_reset_message" msgid="2657049595153992213">"የአስተዳዳሪ መተግበሪያ ስራ ላይ ሊውል አይችልም። የእርስዎን መሣሪያ አሁን ይደመሰሳል።\n\nጥያቄዎች ካለዎት የድርጅትዎን አስተዳዳሪ ያነጋግሩ።"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"ማተም በ<xliff:g id="OWNER_APP">%s</xliff:g> ተሰናክሏል።"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"የእርስዎን የግል መተግበሪያዎች እገዳ ያንሱ"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"መተግበሪያዎች ነገ ይታገዳሉ"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"የእርስዎ አይቲ አስተዳዳሪ የሥራ መገለጫዎ ከ<xliff:g id="DAYS">%1$d</xliff:g> ቀኖች በላይ ባለበት እንዲቆም አይፈቅዱም"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"የስራ መገለጫዎን ያብሩት"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"የስራ መገለጫዎን እስኪያበሩት ድረስ የግል መተግበሪያዎችዎ ታግደዋል"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"የግል መተግበሪያዎችዎ ነገ ይታገዳሉ"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"የሥራ መገለጫን አብራ"</string> <string name="me" msgid="6207584824693813140">"እኔ"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"የጡባዊ አማራጮች"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ሁለቱንም የድምፅ ቁልፎች ወደ ታች ለጥቂት ሰከንዶች መያዝ የተደራሽነት ባሕሪያትን <xliff:g id="SERVICE">%1$s</xliff:g> ያበራል። ይህ የእርስዎ መሣሪያ እንዴት እንደሚሠራ ሊለውጥ ይችላል።\n\nበቅንብሮች > ተደራሽነት ውስጥ ወደ ሌላ ባሕሪ ይህን አቋራጭ መለወጥ ይችላሉ።"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"አብራ"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"አታብራ"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"አብራ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ቅናሽ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> ሙሉ የመሣሪያዎ ቁጥጥር እንዲኖረው ይፈቀድለት?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g>ን ካበሩት መሳሪያዎ የውሂብ ምስጠራን ለማላቅ የማያ ገጽ መቆለፊያዎን አይጠቀምም።"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ሙሉ ቁጥጥር ከተደራሽነት ፍላጎቶች ጋር እርስዎን ለሚያግዝዎት መተግበሪያዎች ተገቢ ነው ሆኖም ግን ለአብዛኛዎቹ መተግበሪያዎች አይሆንም።"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"በእርስዎ አስተዳዳሪ ተዘምኗል"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"እሺ"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"የባትሪ ዕድሜን ለማራዘም፣ የባትሪ ቆጣቢ፦\n·ጨለማ ገጽታን ያበራል\n·የበስተጀርባ እንቅስቃሴን፣ አንዳንድ የሚታዩ ማሳመሪያዎችን፣ እና ሌሎች እንደ “Hey Google” ያሉ ባህሪያትን ያጠፋል ወይም ይገድባል\n\n"<annotation id="url">"የበለጠ ለመረዳት"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"የባትሪ ዕድሜን ለማራዘም፣ የባትሪ ቆጣቢ፦\n·ጨለማ ገጽታን ያበራል\n·የበስተጀርባ እንቅስቃሴን፣ አንዳንድ የሚታዩ ማሳመሪያዎችን፣ እና ሌሎች እንደ “Hey Google” ያሉ ባህሪያትን ያጠፋል ወይም ይገድባል"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"የውሂብ አጠቃቀም እንዲቀንስ ለማገዝ ውሂብ ቆጣቢ አንዳንድ መተግበሪያዎች ከበስተጀርባ ሆነው ውሂብ እንዳይልኩ ወይም እንዳይቀበሉ ይከለክላቸዋል። በአሁኑ ጊዜ እየተጠቀሙበት ያለ መተግበሪያ ውሂብ ሊደርስ ይችላል፣ ነገር ግን ባነሰ ተደጋጋሚነት ሊሆን ይችላል። ይሄ ማለት ለምሳሌ ምስሎችን መታ እስኪያደርጓቸው ድረስ ላይታዩ ይችላሉ ማለት ነው።"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ውሂብ ቆጣቢ ይጥፋ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"አብራ"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ማሳወቂያዎች"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ፈጣን ቅንብሮች"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"የኃይል መገናኛ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"የተከፈለ ማያን ቀያይር"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"የማያ ገጽ ቁልፍ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ቅጽበታዊ ገጽ እይታ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"የተደራሽነት ምናሌ"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> የሥዕል ገላጭ ጽሑፍ አሞሌ።"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ወደ የRESTRICTED ባልዲ ተከትቷል"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>፦"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"ውይይት"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"የቡድን ውይይት"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index d06bc3b51f04..ec049065dc67 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -208,9 +208,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"سيتم محو بيانات جهازك."</string> <string name="factory_reset_message" msgid="2657049595153992213">"تعذّر استخدام تطبيق المشرف. سيتم محو بيانات جهازك الآن.\n\nإذا كانت لديك أسئلة، اتصل بمشرف مؤسستك."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"تم إيقاف الطباعة بواسطة <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"إزالة حظر تطبيقاتك الشخصية"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"سيتم حظر التطبيقات غدًا"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"لا يسمح لك مشرف تكنولوجيا المعلومات بإيقاف الملف الشخصي للعمل مؤقتًا أكثر من <xliff:g id="DAYS">%1$d</xliff:g> يوم."</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"تفعيل الملف الشخصي للعمل"</string> <string name="me" msgid="6207584824693813140">"أنا"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"خيارات الجهاز اللوحي"</string> @@ -724,7 +727,7 @@ </string-array> <string-array name="emailAddressTypes"> <item msgid="7786349763648997741">"المنزل"</item> - <item msgid="435564470865989199">"عمل"</item> + <item msgid="435564470865989199">"العمل"</item> <item msgid="4199433197875490373">"آخر"</item> <item msgid="3233938986670468328">"مخصص"</item> </string-array> @@ -778,7 +781,7 @@ <string name="phoneTypeMms" msgid="1799747455131365989">"رسالة وسائط متعددة"</string> <string name="eventTypeCustom" msgid="3257367158986466481">"مخصص"</string> <string name="eventTypeBirthday" msgid="7770026752793912283">"عيد ميلاد"</string> - <string name="eventTypeAnniversary" msgid="4684702412407916888">"الذكرى السنوية"</string> + <string name="eventTypeAnniversary" msgid="4684702412407916888">"ذكرى سنوية"</string> <string name="eventTypeOther" msgid="530671238533887997">"غير ذلك"</string> <string name="emailTypeCustom" msgid="1809435350482181786">"مخصص"</string> <string name="emailTypeHome" msgid="1597116303154775999">"المنزل"</string> @@ -1719,6 +1722,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"يؤدي الضغط مع الاستمرار لبضع ثوانٍ على كلا مفتاحَي التحكّم في مستوى الصوت إلى تفعيل <xliff:g id="SERVICE">%1$s</xliff:g> وهي إحدى ميزات إمكانية الوصول. يمكن أن يؤدي هذا الإجراء إلى تغيير كيفية عمل جهازك.\n\nيمكنك تغيير هذا الاختصار لاستخدامه مع ميزة أخرى في الإعدادات > أدوات تمكين الوصول."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"تفعيل"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"عدم التفعيل"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"مفعّل"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"غير مفعّل"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"هل تريد السماح لخدمة <xliff:g id="SERVICE">%1$s</xliff:g> بالتحكّم الكامل في جهازك؟"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"في حال تفعيل <xliff:g id="SERVICE">%1$s</xliff:g>، لن يستخدم جهازك ميزة قفل الشاشة لتحسين ترميز البيانات."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"إنّ التحكّم الكامل ليس ملائمًا لمعظم التطبيقات، باستثناء التطبيقات المعنية بسهولة الاستخدام."</string> @@ -1884,8 +1889,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"تم التحديث بواسطة المشرف"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"تم الحذف بواسطة المشرف"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"حسنًا"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"لإطالة عمر البطارية، \"توفير شحن البطارية\":\n·تفعيل \"المظهر الداكن\"\n إيقاف النشاط في الخلفية وأيضًا بعض التأثيرات المرئية والميزات الأخرى، مثلاً \"Ok Google\" أو فرض قيود عليها\n\n"<annotation id="url">"مزيد من المعلومات"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"لإطالة عمر البطارية، \"توفير شحن البطارية\":\n·تفعيل \"المظهر الداكن\"\n إيقاف النشاط في الخلفية وأيضًا بعض التأثيرات المرئية والميزات الأخرى، مثلاً \"Ok Google\" أو فرض قيود عليها."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"للمساعدة في خفض استخدام البيانات، تمنع ميزة \"توفير البيانات\" بعض التطبيقات من إرسال البيانات وتلقّيها في الخلفية. يمكن للتطبيقات المتاحة لديك الآن استخدام البيانات، ولكن لا يمكنها الإكثار من ذلك. وهذا يعني أن الصور مثلاً لا تظهر حتى تنقر عليها."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"هل تريد تفعيل توفير البيانات؟"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"تفعيل"</string> @@ -2174,13 +2181,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"الإشعارات"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"الإعدادات السريعة"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"مربّع حوار الطاقة"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"تبديل \"تقسيم الشاشة\""</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"شاشة القفل"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"لقطة شاشة"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"قائمة \"سهولة الاستخدام\""</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"شريط الشرح لتطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"تم وضع <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> في الحزمة \"محظورة\"."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"محادثة"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"محادثة جماعية"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index ecf0394a20d2..ef193cbd75cb 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"আপোনাৰ ডিভাইচৰ ডেটা মচা হ\'ব"</string> <string name="factory_reset_message" msgid="2657049595153992213">"এই প্ৰশাসক এপটো ব্যৱহাৰ কৰিব নোৱাৰি। এতিয়া আপোনাৰ ডিভাইচটোৰ ডেটা মচা হ\'ব।\n\nআপোনাৰ কিবা প্ৰশ্ন থাকিলে আপোনাৰ প্ৰতিষ্ঠানৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"প্ৰিণ্ট কৰা কাৰ্য <xliff:g id="OWNER_APP">%s</xliff:g>এ অক্ষম কৰি ৰাখিছে।"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"আপোনাৰ ব্যক্তিগত এপ্সমূহ অৱৰোধৰ পৰা আঁতৰাওক"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"এপ্সমূহ কাইলৈ অৱৰোধ কৰা হ’ব"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"আপোনাৰ আইটি প্ৰশাসকে আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইল <xliff:g id="DAYS">%1$d</xliff:g> দিনতকৈ বেছি সময়ৰ বাবে পজ হৈ থকাৰ অনুমতি নিদিয়ে"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"কৰ্মস্থানৰ প্ৰ’ফাইলটো অন কৰক"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"আপুনি নিজৰ কৰ্মস্থানৰ প্ৰ’ফাইলটো অন নকৰালৈকে আপোনাৰ ব্যক্তিগত এপ্সমূহ অৱৰোধ কৰা থাকে"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"আপোনাৰ ব্যক্তিগত এপ্সমূহ কাইলৈ অৱৰোধ কৰা হ’ব"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"কৰ্মস্থানৰ প্ৰ’ফাইল অন কৰক"</string> <string name="me" msgid="6207584824693813140">"মই"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"টে\'বলেটৰ বিকল্পসমূহ"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"দুয়োটা ভলিউম কী কিছুসময়ৰ বাবে ধৰি থাকিলে এটা সাধ্য- সুবিধা <xliff:g id="SERVICE">%1$s</xliff:g> অন কৰে। এইটোৱে আপোনাৰ ডিভাইচটোৱে কাম কৰাৰ ধৰণ সলনি কৰিব পাৰে।\n\nআপুনি ছেটিংসমূহ > সাধ্য-সুবিধাসমূহত এই শ্বৰ্টকাটটো অন্য এটা সুবিধালৈ সলনি কৰিব পাৰে।"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"অন কৰক"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"অন নকৰিব"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"অন কৰা আছে"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"অফ কৰা আছে"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>ক আপোনাৰ ডিভাইচটোৰ সম্পূর্ণ নিয়ন্ত্ৰণ দিবনে?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"যদি আপুনি <xliff:g id="SERVICE">%1$s</xliff:g> অন কৰে, তেন্তে আপোনাৰ ডিভাইচটোৱে ডেটা এনক্ৰিপশ্বনৰ গুণগত মান উন্নত কৰিবলৈ স্ক্ৰীন লক ব্যৱহাৰ নকৰে।"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"আপোনাক সাধ্য সুবিধাৰ প্ৰয়োজনসমূহৰ জৰিয়তে সহায় কৰা এপ্সমূহৰ বাবে সম্পূর্ণ নিয়ন্ত্ৰণৰ সুবিধাটো সঠিক যদিও অধিকাংশ এপৰ বাবে এয়া সঠিক নহয়।"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"আপোনাৰ প্ৰশাসকে আপেডট কৰিছে"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"আপোনাৰ প্ৰশাসকে মচিছে"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"বেটাৰীৰ জীৱনকাল বৃদ্ধি কৰিবলৈ, বেটাৰি সঞ্চয়কাৰীয়ে:\n·গাঢ় ৰঙৰ থীম অন কৰে\n·নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল প্ৰভাৱ আৰু “Hey Google”ৰ দৰে অন্য সুবিধাসমূহ অফ কৰে অথবা সেইবোৰ সীমাবদ্ধ কৰে\n\n"<annotation id="url">"অধিক জানক"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"বেটাৰীৰ জীৱনকাল বৃদ্ধি কৰিবলৈ, বেটাৰি সঞ্চয়কাৰীয়ে:\n·গাঢ় ৰঙৰ থীম অন কৰে\n·নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল প্ৰভাৱ আৰু “Hey Google”ৰ দৰে অন্য সুবিধাসমূহ অফ কৰে অথবা সেইবোৰ সীমাবদ্ধ কৰে"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ডেটা ব্য়ৱহাৰ মাত্ৰা কম কৰিবৰ বাবে ডেটা সঞ্চয়কাৰীয়ে কিছুমান এপক নেপথ্য়ত ডেটা প্ৰেৰণ বা সংগ্ৰহ কৰাত বাধা প্ৰদান কৰে। আপুনি বৰ্তমান ব্য়ৱহাৰ কৰি থকা এটা এপে ডেটা ব্য়ৱহাৰ কৰিব পাৰে, কিন্তু সঘনাই এই কার্য কৰিব নোৱাৰিব পাৰে। ইয়াৰ অৰ্থ এইয়ে হ\'ব পাৰে যে, উদাহৰণস্বৰূপে, আপুনি নিটিপা পর্যন্ত প্ৰতিচ্ছবিসমূহ দেখুওৱা নহ’ব।"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ডেটা সঞ্চয়কাৰী অন কৰিবনে?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"অন কৰক"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"জাননীসমূহ"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ক্ষিপ্ৰ ছেটিংসমূহ"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"পাৱাৰ ডায়লগ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"বিভাজিত স্ক্ৰীন ট’গল কৰক"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"লক স্ক্ৰীন"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্ৰীণশ্বট"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"সাধ্য সুবিধাৰ মেনু"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ কেপশ্বন বাৰ।"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ক সীমাবদ্ধ বাকেটটোত ৰখা হৈছে"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"বাৰ্তালাপ"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"গোটত কৰা বাৰ্তালাপ"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 1e633d390212..2779029e530f 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız təmizlənəcəkdir"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Admin tətbiqini istifadə etmək mümkün deyil. Cihaz indi təmizlənəcək.\n\nSualınız varsa, təşkilatın admini ilə əlaqə saxlayın."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Çap <xliff:g id="OWNER_APP">%s</xliff:g> tərəfindən deaktiv edildi."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Şəxsi tətbiqləri blokdan çıxarın"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Tətbiqlər sabah bloklanacaq"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"İT admininiz iş profilinizə <xliff:g id="DAYS">%1$d</xliff:g> gündən artıq fasilə verilməsinə icazə vermir"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"İş profilinizi aktiv edin"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"İş profilinizi aktiv edənədək şəxsi tətbiqləriniz bloklanır"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Şəxsi tətbiqləriniz sabah bloklanacaq"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"İş profilini aktiv edin"</string> <string name="me" msgid="6207584824693813140">"Mən"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Planşet seçimləri"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyası olan <xliff:g id="SERVICE">%1$s</xliff:g> aktiv olur. Bu, cihazınızın işləmə qaydasını dəyişə bilər.\n\nAyarlar və Əlçatımlılıq bölməsində bu qısayolu başqa bir funksiyata dəyişə bilərsiniz."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktiv edin"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Aktiv etməyin"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTİV"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DEAKTİV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> xidmətinin cihaza tam nəzarət etməsinə icazə verilsin?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> aktiv olarsa, cihazınız data şifrələnməsini genişləndirmək üçün ekran kilidini istifadə etməyəcək."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Tam nəzarət əlçatımlılıq ehtiyaclarınızı ödəyən bəzi tətbiqlər üçün uyğundur."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Admin tərəfindən yeniləndi"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Admin tərəfindən silindi"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Batareyanın ömrünü artırmaq üçün Enerjiyə Qənaət xüsusiyyəti:\n·Qaranlıq temanı aktiv edir\n·Arxa fondakı fəaliyyəti, bəzi vizual effektləri və “Hey Google” kimi digər xüsusiyyətləri deaktiv edir və ya məhdudlaşdırır\n\n"<annotation id="url">"Ətraflı məlumat"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Batareyanın ömrünü artırmaq üçün Enerjiyə Qənaət xüsusiyyəti:\n·Qaranlıq temanı aktiv edir\n·Arxa fondakı fəaliyyəti, bəzi vizual effektləri və “Hey Google” kimi digər xüsusiyyətləri deaktiv edir və ya məhdudlaşdırır"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Data istifadəsini azalatmaq üçün, Data Qanaəti bəzi tətbiqlərin arxafonda data göndərməsinin və qəbulunun qarşısını alır. Hazırda işlətdiyiniz tətbiq dataya daxil ola bilər, ancaq bunu tez-tez edə bilməz. Bu o deməkdir ki, məsələn, Siz üzərinə tıklamadıqca o şəkillər göstərilməyəcək."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Data Qənaəti aktiv edilsin?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivləşdirin"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Bildirişlər"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Sürətli Ayarlar"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Yandırıb-söndürmə dialoqu"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bölünmüş Ekrana keçid"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Kilid Ekranı"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekran şəkli"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Əlçatımlılıq Menyusu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> başlıq paneli."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> MƏHDUDLAŞDIRILMIŞ səbətinə yerləşdirilib"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Söhbət"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Qrup Söhbəti"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index abcecb7b9e93..d12073a9217e 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -202,9 +202,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti obrisan"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Odblokirajte lične aplikacije"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Aplik. će se blokirati sutra"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT administrator vam ne dozvoljava da profil za Work pauzirate više od <xliff:g id="DAYS">%1$d</xliff:g> dana"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Uključite profil za Work"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Lične aplikacije su blokirane dok ne uključite profil za Work"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Lične aplikacije će biti blokirane sutra"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Uključi profil za Work"</string> <string name="me" msgid="6207584824693813140">"Ja"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcije za tablet"</string> @@ -1653,6 +1653,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ako zadržite oba tastera za jačinu zvuka par sekundi, uključuje se <xliff:g id="SERVICE">%1$s</xliff:g>, funkcija pristupačnosti. To može da promeni način rada uređaja.\n\nMožete da promenite funkciju na koju se odnosi ova prečica u odeljku Podešavanja > Pristupačnost."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Uključi"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ne uključuj"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"UKLJUČENO"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ISKLJUČENO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Želite li da dozvolite da usluga <xliff:g id="SERVICE">%1$s</xliff:g> ima potpunu kontrolu nad uređajem?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ako uključite uslugu <xliff:g id="SERVICE">%1$s</xliff:g>, uređaj neće koristiti zaključavanje ekrana da bi poboljšao šifrovanje podataka."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Potpuna kontrola je primerena za aplikacije koje vam pomažu kod usluga pristupačnosti, ali ne i za većinu aplikacija."</string> @@ -1815,8 +1817,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je administrator"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Radi dužeg trajanja baterije, ušteda baterije:\n·uključuje tamnu temu\n·isključuje ili ograničava aktivnosti u pozadini, neke vizuelne efekte i druge funkcije, na primer, „Ok Google“\n\n"<annotation id="url">"Saznajte više"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Radi dužeg trajanja baterije, ušteda baterije:\n·uključuje tamnu temu\n·isključuje ili ograničava aktivnosti u pozadini, neke vizuelne efekte i druge funkcije, na primer, „Ok Google“"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Želite da uključite Uštedu podataka?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string> @@ -2072,13 +2076,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obaveštenja"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brza podešavanja"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijalog napajanja"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Uključite/isključite podeljeni ekran"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključani ekran"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Meni Pristupačnost"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka sa naslovima aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je dodat u segment OGRANIČENO"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Konverzacija"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupna konverzacija"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index eb2f01bc6be1..68c851cdf9cf 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -204,9 +204,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Даныя вашай прылады будуць сцерты"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Немагчыма выкарыстоўваць праграму адміністравання. Звесткі на вашай прыладзе будуць выдалены.\n\nКалі ў вас ёсць пытанні, звярніцеся да адміністратара арганізацыі."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Друк адключаны ўладальнікам праграмы <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Разблакіруйце праграмы"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Прагр. будуць заблак. заўтра"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Ваш ІТ-адміністратар не дазволіў прыпыняць ваш працоўны профіль больш чым на <xliff:g id="DAYS">%1$d</xliff:g> сут."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Уключыце працоўны профіль"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Вашы асабістыя праграмы будуць заблакіраваны, пакуль вы не ўключыце працоўны профіль"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Заўтра будуць заблакіраваны вашы асабістыя праграмы"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Уключыць працоўны профіль"</string> <string name="me" msgid="6207584824693813140">"Я"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Параметры планшэта"</string> @@ -1675,6 +1675,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Утрымліванне націснутымі абедзвюх клавіш гучнасці на працягу некалькіх секунд уключае службу \"<xliff:g id="SERVICE">%1$s</xliff:g>\", якая з\'яўляецца спецыяльнай магчымасцю. У выніку ваша прылада можа пачаць працаваць па-іншаму.\n\nВы можаце задаць гэта спалучэнне клавіш для іншай функцыі ў меню \"Налады > Спецыяльныя магчымасці\"."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Уключыць"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Не ўключаць"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"УКЛЮЧАНА"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ВЫКЛЮЧАНА"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Дазволіць сэрвісу \"<xliff:g id="SERVICE">%1$s</xliff:g>\" мець поўны кантроль над вашай прыладай?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Калі вы ўключыце сэрвіс \"<xliff:g id="SERVICE">%1$s</xliff:g>\", на прыладзе не будзе выкарыстоўвацца блакіроўка экрана для паляпшэння шыфравання даных."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Поўны кантроль прызначаны для сэрвісаў спецыяльных магчымасцей, аднак не падыходзіць для большасці праграм."</string> @@ -1838,8 +1840,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Абноўлены вашым адміністратарам"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Выдалены вашым адміністратарам"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Каб павялічыць тэрмін службы акумулятара, рэжым эканоміі зараду:\n·уключае цёмную тэму;\n·выключае ці абмяжоўвае дзеянні ў фонавым рэжыме, некаторыя візуальныя эфекты і іншыя функцыі, напрыклад \"Ok Google\"\n\n"<annotation id="url">"Даведацца больш"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Каб павялічыць тэрмін службы акумулятара, рэжым эканоміі зараду:\n·уключае цёмную тэму;\n·выключае ці абмяжоўвае дзеянні ў фонавым рэжыме, некаторыя візуальныя эфекты і іншыя функцыі, напрыклад \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"У рэжыме \"Эканомія трафіка\" фонавая перадача для некаторых праграмам адключана. Праграма, якую вы зараз выкарыстоўваеце, можа атрымліваць доступ да даных, але радзей, чым звычайна. Напрыклад, відарысы могуць не загружацца, пакуль вы не націсніце на іх."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Уключыць Эканомію трафіка?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Уключыць"</string> @@ -2106,13 +2110,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Апавяшчэнні"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Хуткія налады"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Дыялогавае акно сілкавання"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Пераключальнік падзеленага экрана"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Экран блакіроўкі"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Здымак экрана"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Меню спецыяльных магчымасцей"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Панэль субцітраў праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" дададзены ў АБМЕЖАВАНУЮ групу"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Размова"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групавая размова"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 9e73d422eb6f..85c18f4ebe3b 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -200,9 +200,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Данните на устройството ви ще бъдат изтрити"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Приложението за администриране не може да се използва. Сега данните на устройството ви ще бъдат изтрити.\n\nАко имате въпроси, свържете се с администратора на организацията си."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Отпечатването е деактивиранo от <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Отблокир. на личните ви прил."</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Прил. ще бъдат блокирани утре"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Системният ви администратор не разрешава поставянето на служебния ви потребителски профил на пауза за повече от <xliff:g id="DAYS">%1$d</xliff:g> дни"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Включване на служебния потребителски профил"</string> <string name="me" msgid="6207584824693813140">"Аз"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Опции за таблета"</string> @@ -1631,6 +1634,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Натиснете двата бутона за силата на звука и ги задръжте за няколко секунди, за да включите функцията за достъпност <xliff:g id="SERVICE">%1$s</xliff:g>. Това може да промени начина, по който работи устройството ви.\n\nМожете да зададете друга функция за този пряк път от „Настройки“ > „Достъпност“."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Включване"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Без включване"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ВКЛ."</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИЗКЛ."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Искате ли да разрешите на <xliff:g id="SERVICE">%1$s</xliff:g> да има пълен контрол над устройството ви?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ако включите <xliff:g id="SERVICE">%1$s</xliff:g>, устройството ви няма да подобрява шифроването на данни посредством опцията ви за заключване на екрана."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Пълният контрол е подходящ за приложенията, които помагат на потребителите със специални нужди, но не и за повечето приложения."</string> @@ -1792,8 +1797,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Актуализирано от администратора ви"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Изтрито от администратора ви"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"С цел удължаване на живота на батерията режимът за запазването ѝ:\n·включва тъмната тема;\n·изключва или ограничава активността на заден план, някои визуални ефекти и други функции, като например „Ok Google“.\n\n"<annotation id="url">"Научете повече"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"С цел удължаване на живота на батерията режимът за запазването ѝ:\n·включва тъмната тема;\n·изключва или ограничава активността на заден план, някои визуални ефекти и други функции, като например „Ok Google“."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"С цел намаляване на преноса на данни функцията за икономия на данни не позволява на някои приложения да изпращат или получават данни на заден план. Понастоящем използвано от вас приложение може да използва данни, но по-рядко. Това например може да означава, че изображенията не се показват, докато не ги докоснете."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Ще вкл. ли „Икономия на данни“?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Включване"</string> @@ -2038,13 +2045,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Известия"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Бързи настройки"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Диалогов прозорец за захранването"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Превключване на разделения екран"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заключен екран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Екранна снимка"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Меню за достъпност"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Лента за надписи на <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакетът <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е поставен в ОГРАНИЧЕНИЯ контейнер"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Разговор"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групов разговор"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"Над <xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 9f064a2eca7a..41683e886620 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"আপনার ডিভাইসটি মুছে ফেলা হবে"</string> <string name="factory_reset_message" msgid="2657049595153992213">"অ্যাডমিন অ্যাপটি ব্যবহার করা যাবে না। আপনার ডিভাইসে থাকা সবকিছু এখন মুছে ফেলা হবে।\n\nকোনও প্রশ্ন থাকলে আপনার প্রতিষ্ঠানের অ্যাডমিনের সাথে যোগাযোগ করুন।"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> প্রিন্টিং বন্ধ রেখেছে।"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ব্যক্তিগত অ্যাপ আনব্লক করুন"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"কাল অ্যাপগুলি ব্লক করা হবে"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"আপনার আইটি অ্যাডমিন আপনার অফিস প্রোফাইল <xliff:g id="DAYS">%1$d</xliff:g> দিনের বেশি পজ করে রাখার অনুমতি দেয় না"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"অফিসের প্রোফাইল চালু করুন"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"আপনার অফিসের প্রোফাইল চালু না করা পর্যন্ত আপনার ব্যক্তিগত অ্যাপ ব্লক থাকে"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"আগামীকাল আপনার ব্যক্তিগত অ্যাপ ব্লক করা হবে"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"অফিস প্রোফাইল চালু করুন"</string> <string name="me" msgid="6207584824693813140">"আমাকে"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ট্যাবলেট বিকল্পগুলি"</string> @@ -1631,6 +1631,10 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"উভয় ভলিউম কী কয়েক সেকেন্ড ধরে থাকলে <xliff:g id="SERVICE">%1$s</xliff:g> চালু হয়ে যাবে। এটি একটি অ্যাক্সেসিবিলিটি ফিচার। এর ফলে, আপনার ডিভাইস কীভাবে কাজ করবে সেটিতে পরিবর্তন হতে পারে।\n\nসেটিংস > অ্যাক্সেসিবিলিটি থেকে আপনি এই শর্টকাট পরিবর্তন করতে পারবেন।"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"চালু করুন"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"চালু করবেন না"</string> + <!-- no translation found for accessibility_shortcut_menu_item_status_on (6608392117189732543) --> + <skip /> + <!-- no translation found for accessibility_shortcut_menu_item_status_off (5531598275559472393) --> + <skip /> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> অ্যাপটিকে আপনার ডিভাইসে সম্পূর্ণ নিয়ন্ত্রণের অনুমতি দিতে চান?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> চালু করলে, ডেটা এনক্রিপশন উন্নত করার উদ্দেশ্যে আপনার ডিভাইস স্ক্রিন লক ব্যবহার করবে না।"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"যে অ্যাপগুলি আপনাকে অ্যাক্সেসিবিলিটির প্রয়োজন মেটাতে সাহায্য করে সেই অ্যাপগুলির জন্য সম্পূর্ণ নিয়ন্ত্রণের বিষয়টি উপযুক্ত, কিন্তু তা বলে সমস্ত অ্যাপের জন্য নয়।"</string> @@ -1792,8 +1796,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"আপনার প্রশাসক আপডেট করেছেন"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"আপনার প্রশাসক মুছে দিয়েছেন"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ব্যাটারি আরও বেশিক্ষণ চালাতে, ব্যাটারি সেভার:\n·গাঢ় থিম চালু করে\n·ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট, এবং “হ্যালো Google”-এর মতো অন্যান্য ফিচার বন্ধ বা সীমাবদ্ধ করে\n\n"<annotation id="url">"আরও জানুন"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ব্যাটারি আরও বেশিক্ষণ চালাতে, ব্যাটারি সেভার:\n·গাঢ় থিম চালু করে\n·ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট এবং “হ্যালো Google”-এর মতো অন্যান্য ফিচার বন্ধ বা সীমাবদ্ধ করে"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ডেটার ব্যবহার কমাতে সহায়তা করার জন্য, ডেটা সেভার ব্যাকগ্রাউন্ডে কিছু অ্যাপ্লিকেশনকে ডেটা পাঠাতে বা গ্রহণ করতে বাধা দেয়৷ আপনি বর্তমানে এমন একটি অ্যাপ্লিকেশন ব্যবহার করছেন যেটি ডেটা অ্যাক্সেস করতে পারে, তবে সেটি কমই করে৷ এর ফলে যা হতে পারে, উদাহরণস্বরূপ, আপনি ছবির উপর ট্যাপ না করা পর্যন্ত সেগুলি দেখানো হবে না৷"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ডেটা সেভার চালু করবেন?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"চালু করুন"</string> @@ -2038,13 +2044,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"বিজ্ঞপ্তি"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"দ্রুত সেটিংস"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"পাওয়ার ডায়লগ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"স্প্লিট স্ক্রিন টগল করুন"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"লক স্ক্রিন"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্রিনশট"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"অ্যাক্সেসিবিলিটি মেনু"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর ক্যাপশন বার।"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> সীমাবদ্ধ গ্রুপে অন্তর্ভুক্ত করা হয়েছে"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"কথোপকথন"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"গ্রুপ কথোপকথন"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index d4fee2ef051f..77991dbf8d00 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -202,9 +202,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti izbrisan"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Nije moguće koristiti aplikaciju administratora. Potpuno će se izbrisati podaci na vašem uređaju.\n\nAko imate pitanja, obratite se administratoru svoje organizacije."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Deblokirajte lične aplikacije"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Sutra se blokiraju aplikacije"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT administrator ne dozvoljava da pauzirate radni profil duže od <xliff:g id="DAYS">%1$d</xliff:g> dana"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Uključite radni profil"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vaše lične aplikacije će biti blokirane dok ne uključite radni profil"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Vaše lične aplikacije će se blokirati sutra"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Uključi radni profil"</string> <string name="me" msgid="6207584824693813140">"Ja"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcije tableta"</string> @@ -1655,6 +1655,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ako nekoliko sekundi držite pritisnute obje tipke za jačinu zvuka, uključit ćete funkciju pristupačnosti <xliff:g id="SERVICE">%1$s</xliff:g>. Ovo može promijeniti način rada uređaja.\n\nOvu prečicu možete zamijeniti drugom funkcijom u odjeljku Postavke > Pristupačnost."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Uključi"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nemoj uključivati"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"UKLJUČENO"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ISKLJUČENO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Dozvoliti da usluga <xliff:g id="SERVICE">%1$s</xliff:g> ima punu kontrolu nad vašim uređajem?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ako uključite uslugu <xliff:g id="SERVICE">%1$s</xliff:g>, uređaj neće koristiti zaključavanje ekrana za poboljšanje šifriranja podataka."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Puna kontrola je prikladna za aplikacije koje vam pomažu kod potreba za pristupačnosti, ali nije za većinu aplikacija."</string> @@ -1817,8 +1819,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je vaš administrator"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je vaš administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Uredu"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Radi produženja vijeka trajanja baterije, Ušteda baterije:\n·Uključuje Tamnu temu\n·Isključuje ili ograničava aktivnosti u pozadini, određene vizuelne efekte i druge funkcije kao što je \"Hej Google\"\n\n"<annotation id="url">"Saznajte više"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Radi produženja vijeka trajanja baterije, Ušteda baterije:\n·Uključuje Tamnu temu\n·Isključuje ili ograničava aktivnosti u pozadini, određene vizuelne efekte i druge funkcije kao što je \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Radi smanjenja prijenosa podataka, Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali će to činiti rjeđe. Naprimjer, to može značiti da se slike ne prikazuju dok ih ne dodirnete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti Uštedu podataka?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string> @@ -2074,13 +2078,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obavještenja"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brze postavke"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijaloški okvir za napajanje"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Uključi/isključi podijeljeni ekran"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključavanje ekrana"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Meni za pristupačnost"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka za natpis aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je stavljen u odjeljak OGRANIČENO"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Razgovor"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupni razgovor"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index d7211bd3b954..64aa7f90243e 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"El contingut del dispositiu s\'esborrarà"</string> <string name="factory_reset_message" msgid="2657049595153992213">"No es pot utilitzar l\'aplicació d\'administració. S\'esborraran les dades del dispositiu.\n\nSi tens cap dubte, contacta amb l\'administrador de la teva organització."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ha desactivat la impressió."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desbloqueja les apps personals"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Les apps es bloquejaran demà"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"L\'administrador de TI no permet posar en pausa el teu perfil de treball durant més de: <xliff:g id="DAYS">%1$d</xliff:g> dies"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activa el perfil de treball"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Les teves aplicacions personals estan bloquejades fins que activis el perfil de treball"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Les aplicacions personals es bloquejaran demà"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Activa el perfil de treball"</string> <string name="me" msgid="6207584824693813140">"Mi"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcions de la tauleta"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Si mantens premudes les dues tecles de volum durant uns segons, la funció d\'accessibilitat <xliff:g id="SERVICE">%1$s</xliff:g> s\'activarà. Això podria canviar el funcionament del teu dispositiu.\n\nPots canviar la funció d\'aquesta drecera a Configuració > Accessibilitat."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activa"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"No activis"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVAT"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESACTIVAT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vols permetre que <xliff:g id="SERVICE">%1$s</xliff:g> controli el teu dispositiu per complet?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si actives <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositiu no farà servir el bloqueig de pantalla per millorar l\'encriptació de dades."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"El control total és adequat per a les aplicacions que t\'ajuden amb l\'accessibilitat, però no per a la majoria de les aplicacions."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualitzat per l\'administrador"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Per allargar la durada de la bateria, el mode Estalvi de bateria:\n Activa el tema fosc\n Desactiva o restringeix l\'activitat en segon pla, alguns efectes visuals i altres funcions com \"Ok Google\"\n\n"<annotation id="url">"Més informació"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Per allargar la durada de la bateria, el mode Estalvi de bateria:\n Activa el tema fosc\n Desactiva o restringeix l\'activitat en segon pla, alguns efectes visuals i altres funcions com \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Per reduir l\'ús de dades, la funció Economitzador de dades evita que determinades aplicacions enviïn o rebin dades en segon pla. L\'aplicació que estiguis fent servir podrà accedir a les dades, però menys sovint. Això vol dir, per exemple, que les imatges no es mostraran fins que no les toquis."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Activar Economitzador de dades?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activa"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificacions"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Configuració ràpida"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Quadre de diàleg d\'engegada"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Commuta Pantalla dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueig"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menú d\'accessibilitat"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de títol de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> s\'ha transferit al segment RESTRINGIT"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversa"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversa de grup"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 8de20cbd1943..d1b0b5b235ee 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -204,9 +204,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Zařízení bude vymazáno"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Aplikaci pro správu nelze použít. Zařízení teď bude vymazáno.\n\nV případě dotazů vám pomůže administrátor organizace."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Aplikace <xliff:g id="OWNER_APP">%s</xliff:g> tisk zakazuje."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Odblokujte osobní aplikace"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Aplikace budou zítra zablokovány"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Administrátor IT nepovoluje pozastavení pracovního profilu na déle než tento počet dní: <xliff:g id="DAYS">%1$d</xliff:g>"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Zapněte pracovní profil"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vaše osobní aplikace jsou zablokovány, dokud nezapnete pracovní profil"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Vaše osobní aplikace budou zítra zablokovány"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Zapnout pracovní profil"</string> <string name="me" msgid="6207584824693813140">"Já"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Možnosti tabletu"</string> @@ -1675,6 +1675,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Podržením obou tlačítek hlasitosti po dobu několika sekund zapnete funkci pro usnadnění přístupu <xliff:g id="SERVICE">%1$s</xliff:g>. Tato funkce může změnit fungování zařízení.\n\nZkratku můžete nastavit na jinou funkci v Nastavení > Přístupnost."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Zapnout"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nezapínat"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ZAP"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VYP"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Chcete službě <xliff:g id="SERVICE">%1$s</xliff:g> povolit, aby nad vaším zařízením měla plnou kontrolu?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Pokud zapnete službu <xliff:g id="SERVICE">%1$s</xliff:g>, zařízení nebude používat zámek obrazovky k vylepšení šifrování dat."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Plná kontrola je vhodná u aplikací, které vám pomáhají s usnadněním přístupu, nikoli u většiny aplikací."</string> @@ -1838,8 +1840,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizováno administrátorem"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Smazáno administrátorem"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Spořič baterie za účelem úspory energie:\n·zapne tmavý motiv,\n·vypne nebo omezí aktivitu na pozadí, některé vizuální efekty a další funkce jako „Ok Google“\n\n"<annotation id="url">"Další informace"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Spořič baterie za účelem úspory energie:\n·zapne tmavý motiv,\n·vypne nebo omezí aktivitu na pozadí, některé vizuální efekty a další funkce jako „Ok Google“"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Spořič dat z důvodu snížení využití dat některým aplikacím brání v odesílání nebo příjmu dat na pozadí. Aplikace, kterou právě používáte, data přenášet může, ale může tak činit méně často. V důsledku toho se například obrázky nemusejí zobrazit, dokud na ně neklepnete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Chcete zapnout Spořič dat?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Zapnout"</string> @@ -2106,13 +2110,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Oznámení"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Rychlé nastavení"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialogové okno k napájení"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Přepnout rozdělenou obrazovku"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Obrazovka uzamčení"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snímek obrazovky"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Nabídka usnadnění přístupu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Popisek aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balíček <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> byl vložen do sekce OMEZENO"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Konverzace"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Skupinová konverzace"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 2c135fbdf124..3bb64cdc81f4 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Enheden slettes"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Administrationsappen kan ikke bruges. Enheden vil nu blive ryddet. \n\nKontakt din organisations administrator, hvis du har spørgsmål."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Udskrivning er deaktiveret af <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Fjern blokeringen af personlige apps"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Dine apps blokeres i morgen"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Din it-administrator tillader ikke, at din arbejdsprofil sættes på pause i mere end <xliff:g id="DAYS">%1$d</xliff:g> dage"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Aktivér din arbejdsprofil"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Dine personlige apps er blokeret, indtil du aktiverer din arbejdsprofil"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Dine personlige apps blokeres i morgen"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Aktivér arbejdsprofil"</string> <string name="me" msgid="6207584824693813140">"Mig"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Valgmuligheder for tabletcomputeren"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hvis du holder begge lydstyrkeknapperne nede i et par sekunder, aktiveres hjælpefunktionen <xliff:g id="SERVICE">%1$s</xliff:g>. Det kan ændre på, hvordan din enhed fungerer.\n\nDu kan ændre denne genvej til en anden funktion i Indstillinger > Hjælpefunktioner."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktivér"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Aktivér ikke"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"TIL"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"FRA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vil du give <xliff:g id="SERVICE">%1$s</xliff:g> fuld kontrol over din enhed?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Hvis du aktiverer <xliff:g id="SERVICE">%1$s</xliff:g>, vil enheden ikke benytte skærmlåsen til at forbedre datakrypteringen."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Fuld kontrol er velegnet til apps, der hjælper dig med hjælpefunktioner, men ikke de fleste apps."</string> @@ -1792,11 +1794,13 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Opdateret af din administrator"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet af din administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Batterisparefunktionen gør følgende for at spare på batteriet:\n·Aktiverer Mørkt tema\n·Deaktiverer eller begrænser aktivitet i baggrunden, visse visuelle effekter og andre funktioner som f.eks. \"Hey Google\"\n\n"<annotation id="url">"Få flere oplysninger"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Batterisparefunktionen gør følgende for at spare på batteriet:\n·Aktiverer Mørkt tema\n·Deaktiverer eller begrænser aktivitet i baggrunden, visse visuelle effekter og andre funktioner som f.eks. \"Hey Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Datasparefunktionen forhindrer nogle apps i at sende eller modtage data i baggrunden for at reducere dataforbruget. En app, der er i brug, kan få adgang til data, men gør det måske ikke så ofte. Dette kan f.eks. betyde, at billeder ikke vises, før du trykker på dem."</string> - <string name="data_saver_enable_title" msgid="7080620065745260137">"Vil du slå Datasparefunktion til?"</string> - <string name="data_saver_enable_button" msgid="4399405762586419726">"Slå til"</string> + <string name="data_saver_enable_title" msgid="7080620065745260137">"Vil du aktivere Datasparefunktion?"</string> + <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivér"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273"> <item quantity="one">I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> <item quantity="other">I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifikationer"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Kvikmenu"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialogboks om strøm"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Slå Opdelt skærm til eller fra"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låseskærm"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menuen Hjælpefunktioner"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Titellinje for <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blevet placeret i samlingen BEGRÆNSET"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Samtale"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Gruppesamtale"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 3567a96b8dde..30cbf85763ea 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Die Daten auf deinem Gerät werden gelöscht."</string> <string name="factory_reset_message" msgid="2657049595153992213">"Die Admin-App kann nicht verwendet werden. Die Daten auf deinem Gerät werden nun gelöscht.\n\nBitte wende dich bei Fragen an den Administrator deiner Organisation."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Drucken wurde von <xliff:g id="OWNER_APP">%s</xliff:g> deaktiviert."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Blockierung privater Apps aufheben"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apps werden morgen blockiert"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Dein IT-Administrator hat festgelegt, dass dein Arbeitsprofil nicht länger als <xliff:g id="DAYS">%1$d</xliff:g> Tage pausiert werden darf"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Arbeitsprofil aktivieren"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Deine privaten Apps werden blockiert, bis du dein Arbeitsprofil aktivierst"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Deine privaten Apps werden morgen blockiert"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Arbeitsprofil aktivieren"</string> <string name="me" msgid="6207584824693813140">"Eigene"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet-Optionen"</string> @@ -1112,7 +1112,7 @@ <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Der Speicherplatz reicht nicht für das System aus. Stelle sicher, dass 250 MB freier Speicherplatz vorhanden sind, und starte das Gerät dann neu."</string> <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird ausgeführt"</string> <string name="app_running_notification_text" msgid="5120815883400228566">"Für weitere Informationen oder zum Beenden der App tippen."</string> - <string name="ok" msgid="2646370155170753815">"Ok"</string> + <string name="ok" msgid="2646370155170753815">"OK"</string> <string name="cancel" msgid="6908697720451760115">"Abbrechen"</string> <string name="yes" msgid="9069828999585032361">"Ok"</string> <string name="no" msgid="5122037903299899715">"Abbrechen"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Wenn du beide Lautstärketasten einige Sekunden lang gedrückt hältst, aktivierst du die Bedienungshilfe \"<xliff:g id="SERVICE">%1$s</xliff:g>\". Dadurch kann sich die Funktionsweise deines Geräts ändern.\n\nUnter \"Einstellungen > \"Bedienungshilfen\" kannst du dieser Verknüpfung eine andere Funktion zuweisen."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktivieren"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nicht aktivieren"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AN"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AUS"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> die vollständige Kontrolle über dein Gerät geben?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Wenn du <xliff:g id="SERVICE">%1$s</xliff:g> aktivierst, verwendet dein Gerät nicht die Displaysperre, um die Datenverschlüsselung zu verbessern."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Die vollständige Kontrolle sollte nur für die Apps aktiviert werden, die dir den Zugang zu den App-Funktionen erleichtern. Das ist in der Regel nur ein kleiner Teil der Apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Von deinem Administrator aktualisiert"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Von deinem Administrator gelöscht"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Der Energiesparmodus sorgt für eine längere Akkulaufzeit:\n·Das dunkle Design wird aktiviert\n·Hintergrundaktivitäten, einige optische Effekte und weitere Funktionen wie \"Ok Google\" werden abgeschaltet oder eingeschränkt\n\n"<annotation id="url">"Weitere Informationen"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Der Energiesparmodus sorgt für eine längere Akkulaufzeit:\n·Das dunkle Design wird aktiviert\n·Hintergrundaktivitäten, einige optische Effekte und weitere Funktionen wie \"Ok Google\" werden abgeschaltet oder eingeschränkt"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Der Datensparmodus verhindert zum einen, dass manche Apps im Hintergrund Daten senden oder empfangen, sodass weniger Daten verbraucht werden. Zum anderen werden die Datenzugriffe der gerade aktiven App eingeschränkt, was z. B. dazu führen kann, dass Bilder erst angetippt werden müssen, bevor sie sichtbar werden."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Datensparmodus aktivieren?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivieren"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Benachrichtigungen"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Schnelleinstellungen"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Kleines Fenster für Akkustand"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"\"Bildschirm teilen\" ein-/ausschalten"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Sperrbildschirm"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menü \"Bedienungshilfen\""</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Untertitelleiste von <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> wurde in den BESCHRÄNKT-Bucket gelegt"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Unterhaltung"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Gruppenunterhaltung"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 05b5e5281f7d..2b4d6a7f88eb 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Η συσκευή σας θα διαγραφεί"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Δεν είναι δυνατή η χρήση της εφαρμογής διαχειριστή. Η συσκευή σας θα διαγραφεί.\n\nΕάν έχετε ερωτήσεις, επικοινωνήστε με τον διαχειριστή του οργανισμού σας."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Η εκτύπωση απενεργοποιήθηκε από τον χρήστη <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Κατ. αποκλ. προσ. εφαρμογών"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Αποκλεισμός εφαρμογών αύριο"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Ο διαχειριστής IT δεν επιτρέπει την παύση του προφίλ εργασίας σας για περισσότερες από <xliff:g id="DAYS">%1$d</xliff:g> ημέρες."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Ενεργοπ. το προφίλ εργασίας"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Οι προσωπικές σας εφαρμογές αποκλείονται μέχρι να ενεργοποιήσετε το προφίλ εργασίας σας."</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Οι προσωπικές εφαρμογές σας θα αποκλειστούν αύριο"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Ενεργοποίηση προφίλ εργασίας"</string> <string name="me" msgid="6207584824693813140">"Για εμένα"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Επιλογές tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Μπορείτε να ενεργοποιήσετε τη λειτουργία <xliff:g id="SERVICE">%1$s</xliff:g>, η οποία είναι μία από τις λειτουργίες προσβασιμότητας, πατώντας παρατεταμένα ταυτόχρονα τα δύο πλήκτρα έντασης ήχου για μερικά δευτερόλεπτα. Αυτό ενδέχεται να αλλάξει τον τρόπο λειτουργίας της συσκευής σας.\n\nΜπορείτε να αλλάξετε αυτή τη συντόμευση σε μια άλλη λειτουργία στις Ρυθμίσεις > Προσβασιμότητα."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ενεργοποίηση"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Να μην ενεργοποιηθούν"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ΕΝΕΡΓΟ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ΑΝΕΝΕΡΓΟ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Να επιτρέπεται στην υπηρεσία <xliff:g id="SERVICE">%1$s</xliff:g> να έχει τον πλήρη έλεγχο της συσκευής σας;"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Εάν ενεργοποιήσετε την υπηρεσία <xliff:g id="SERVICE">%1$s</xliff:g>, η συσκευή σας δεν θα χρησιμοποιεί το κλείδωμα οθόνης για τη βελτίωση της κρυπτογράφησης δεδομένων."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Ο πλήρης έλεγχος είναι κατάλληλος για εφαρμογές που εξυπηρετούν τις ανάγκες προσβασιμότητάς σας, αλλά όχι για όλες τις εφαρμογές."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Ενημερώθηκε από τον διαχειριστή σας"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Διαγράφηκε από τον διαχειριστή σας"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Για την επέκταση της διάρκειας ζωής της μπαταρίας σας, η Εξοικονόμηση μπαταρίας:\n·Ενεργοποιεί το Σκούρο θέμα\n·Απενεργοποιεί ή περιορίζει τη δραστηριότητα παρασκηνίου, ορισμένα οπτικά εφέ και άλλες λειτουργίες όπως την εντολή \"Hey Google\".\n\n"<annotation id="url">"Μάθετε περισσότερα"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Για την επέκταση της διάρκειας ζωής της μπαταρίας σας, η Εξοικονόμηση μπαταρίας:\n·Ενεργοποιεί το Σκούρο θέμα\n·Απενεργοποιεί ή περιορίζει τη δραστηριότητα παρασκηνίου, ορισμένα οπτικά εφέ και άλλες λειτουργίες όπως την εντολή \"Hey Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Προκειμένου να μειωθεί η χρήση δεδομένων, η Εξοικονόμηση δεδομένων αποτρέπει την αποστολή ή λήψη δεδομένων από ορισμένες εφαρμογές στο παρασκήνιο. Μια εφαρμογή που χρησιμοποιείτε αυτήν τη στιγμή μπορεί να χρησιμοποιήσει δεδομένα αλλά με μικρότερη συχνότητα. Για παράδειγμα, οι εικόνες μπορεί να μην εμφανίζονται μέχρι να τις πατήσετε."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Ενεργ.Εξοικονόμησης δεδομένων;"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ενεργοποίηση"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Ειδοποιήσεις"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Γρήγορες ρυθμίσεις"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Παράθυρο διαλόγου λειτουργίας συσκευής"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Εναλλαγή διαχωρισμού οθόνης"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Οθόνη κλειδώματος"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Στιγμιότυπο οθόνης"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Μενού προσβασιμότητας"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Γραμμή υποτίτλων για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Το πακέτο <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> τοποθετήθηκε στον κάδο ΠΕΡΙΟΡΙΣΜΕΝΗΣ ΠΡΟΣΒΑΣΗΣ."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Συνομιλία"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Ομαδική συνομιλία"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index d7047c57a238..b20891d3ab74 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Unblock your personal apps"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apps will be blocked tomorrow"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Your IT admin doesn’t allow your work profile to be paused for more than <xliff:g id="DAYS">%1$d</xliff:g> days"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Turn on your work profile"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Your personal apps are blocked until you turn on your work profile"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Your personal apps will be blocked tomorrow"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Turn on work profile"</string> <string name="me" msgid="6207584824693813140">"Me"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet options"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Holding down both volume keys for a few seconds turns on <xliff:g id="SERVICE">%1$s</xliff:g>, an accessibility feature. This may change how your device works.\n\nYou can change this shortcut to another feature in Settings > Accessibility."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Turn on"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Don’t turn on"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Quick Settings"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Power Dialogue"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Accessibility menu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Group conversation"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index a7ab4275e89a..91b0cab36894 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Unblock your personal apps"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apps will be blocked tomorrow"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Your IT admin doesn’t allow your work profile to be paused for more than <xliff:g id="DAYS">%1$d</xliff:g> days"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Turn on your work profile"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Your personal apps are blocked until you turn on your work profile"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Your personal apps will be blocked tomorrow"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Turn on work profile"</string> <string name="me" msgid="6207584824693813140">"Me"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet options"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Holding down both volume keys for a few seconds turns on <xliff:g id="SERVICE">%1$s</xliff:g>, an accessibility feature. This may change how your device works.\n\nYou can change this shortcut to another feature in Settings > Accessibility."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Turn on"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Don’t turn on"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Quick Settings"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Power Dialogue"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Accessibility menu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Group conversation"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index d7047c57a238..b20891d3ab74 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Unblock your personal apps"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apps will be blocked tomorrow"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Your IT admin doesn’t allow your work profile to be paused for more than <xliff:g id="DAYS">%1$d</xliff:g> days"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Turn on your work profile"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Your personal apps are blocked until you turn on your work profile"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Your personal apps will be blocked tomorrow"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Turn on work profile"</string> <string name="me" msgid="6207584824693813140">"Me"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet options"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Holding down both volume keys for a few seconds turns on <xliff:g id="SERVICE">%1$s</xliff:g>, an accessibility feature. This may change how your device works.\n\nYou can change this shortcut to another feature in Settings > Accessibility."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Turn on"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Don’t turn on"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Quick Settings"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Power Dialogue"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Accessibility menu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Group conversation"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index d7047c57a238..b20891d3ab74 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Unblock your personal apps"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apps will be blocked tomorrow"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Your IT admin doesn’t allow your work profile to be paused for more than <xliff:g id="DAYS">%1$d</xliff:g> days"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Turn on your work profile"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Your personal apps are blocked until you turn on your work profile"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Your personal apps will be blocked tomorrow"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Turn on work profile"</string> <string name="me" msgid="6207584824693813140">"Me"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet options"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Holding down both volume keys for a few seconds turns on <xliff:g id="SERVICE">%1$s</xliff:g>, an accessibility feature. This may change how your device works.\n\nYou can change this shortcut to another feature in Settings > Accessibility."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Turn on"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Don’t turn on"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Quick Settings"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Power Dialogue"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Accessibility menu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Group conversation"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 77d2f3160bbc..ed957de9303d 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organization\'s admin."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Unblock your personal apps"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apps will be blocked tomorrow"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Your IT admin doesn’t allow your work profile to be paused for more than <xliff:g id="DAYS">%1$d</xliff:g> days"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Turn on your work profile"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Your personal apps are blocked until you turn on your work profile"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Your personal apps will be blocked tomorrow"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Turn on work profile"</string> <string name="me" msgid="6207584824693813140">"Me"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet options"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Holding down both volume keys for a few seconds turns on <xliff:g id="SERVICE">%1$s</xliff:g>, an accessibility feature. This may change how your device works.\n\nYou can change this shortcut to another feature in Settings > Accessibility."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Turn on"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Don’t turn on"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> @@ -1792,8 +1794,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects, and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation>""</string> - <string name="battery_saver_description" msgid="7618492104632328184">"To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects, and other features like “Hey Google”"</string> + <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects, and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation>""</string> + <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects, and other features like “Hey Google”"</string> <string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string> @@ -2038,13 +2040,14 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Quick Settings"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Power Dialog"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Accessibility Menu"</string> + <string name="accessibility_system_action_accessibility_button_label" msgid="5941347017132886642">"On-screen Accessibility Shortcut"</string> + <string name="accessibility_system_action_accessibility_button_chooser_label" msgid="6973618519666227981">"On-screen Accessibility Shortcut Chooser"</string> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sent an image"</string> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Group Conversation"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 0fc7ec58523b..5afebbd48921 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Se borrarán los datos del dispositivo"</string> <string name="factory_reset_message" msgid="2657049595153992213">"No se puede usar la app de administrador. Ahora se borrará tu dispositivo.\n\nSi tienes preguntas, comunícate con el administrador de tu organización."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> inhabilitó la impresión."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desbloquea apps personales"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Las apps se bloquearán mañana"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Tu administrador de TI no permite que se pause el perfil de trabajo durante más de <xliff:g id="DAYS">%1$d</xliff:g> días"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activa tu perfil de trabajo"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Las apps personales estarán bloqueadas hasta que actives tu perfil de trabajo"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Mañana se bloquearán tus apps personales"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Activar perfil de trabajo"</string> <string name="me" msgid="6207584824693813140">"Yo"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opciones de tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Si mantienes presionadas ambas teclas de volumen durante unos segundos, se activará la función de accesibilidad <xliff:g id="SERVICE">%1$s</xliff:g>. Esto podría cambiar la forma en que funciona tu dispositivo.\n\nPuedes cambiar este acceso directo a otra función en Configuración > Accesibilidad."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activar"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"No activar"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SÍ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"¿Deseas permitir que <xliff:g id="SERVICE">%1$s</xliff:g> tenga el control total del dispositivo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si activas <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositivo no utilizará el bloqueo de pantalla para mejorar la encriptación de datos."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"El control total es apropiado para las apps que te ayudan con las necesidades de accesibilidad, pero no para la mayoría de las apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Tu administrador actualizó este paquete"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Tu administrador borró este paquete"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Para extender la duración de batería, el Ahorro de batería hace lo siguiente:\n·Activa el Tema oscuro.\n·Desactiva o restringe la actividad en segundo plano, algunos efectos visuales y otras funciones, como \"Ok Google\".\n\n"<annotation id="url">"Más información"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Para extender la duración de batería, el modo Ahorro de batería hace lo siguiente:\n·Activa el Tema oscuro.\n·Desactiva o restringe la actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Para reducir el uso de datos, el modo Ahorro de datos evita que algunas apps envíen y reciban datos en segundo plano. La app que estés usando podrá acceder a los datos, pero con menor frecuencia. De esta forma, por ejemplo, las imágenes no se mostrarán hasta que las presiones."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"¿Deseas activar Ahorro de datos?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificaciones"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Configuración rápida"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Diálogo de encendido"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activar o desactivar pantalla dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloquear pantalla"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menú de accesibilidad"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el depósito RESTRICTED"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversación"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversación en grupo"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"+<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index b923564be9b9..1288a1315ae0 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Tu dispositivo se borrará"</string> <string name="factory_reset_message" msgid="2657049595153992213">"No se puede utilizar la aplicación de administración. Se borrarán todos los datos del dispositivo.\n\nSi tienes alguna pregunta, ponte en contacto con el administrador de tu organización."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ha inhabilitado la impresión."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desbloquear apps personales"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Las apps se bloquearán mañana"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Tu administrador de TI no te permite pausar el perfil de trabajo durante más de <xliff:g id="DAYS">%1$d</xliff:g> días"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activa tu perfil de trabajo"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Tus aplicaciones personales estarán bloqueadas hasta que actives tu perfil de trabajo"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Tus aplicaciones personales se bloquearán mañana"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Activar perfil de trabajo"</string> <string name="me" msgid="6207584824693813140">"Yo"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opciones del tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Al mantener pulsadas ambas teclas de volumen durante unos segundos se activa <xliff:g id="SERVICE">%1$s</xliff:g>, una función de accesibilidad. Esta función puede modificar el funcionamiento del dispositivo.\n\nPuedes asignar este acceso directo a otra función en Ajustes > Accesibilidad."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activar"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"No activar"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SÍ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"¿Permitir que <xliff:g id="SERVICE">%1$s</xliff:g> pueda controlar totalmente tu dispositivo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si activas <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositivo no utilizará el bloqueo de pantalla para mejorar el cifrado de datos."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"El control total es adecuado para las aplicaciones de accesibilidad, pero no para la mayoría de las aplicaciones."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado por el administrador"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado por el administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Para que la batería dure más, el modo Ahorro de batería:\n· Activa el tema oscuro\n· Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"\n\n"<annotation id="url">"Más información"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Para que la batería dure más, el modo Ahorro de batería:\n· Activa el tema oscuro\n· Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"El modo Ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano, lo que puede reducir el uso de datos. Una aplicación activa puede acceder a los datos, aunque con menos frecuencia. Esto significa que es posible que, por ejemplo, algunas imágenes no se muestren hasta que las toques."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"¿Activar Ahorro de datos?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificaciones"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Ajustes rápidos"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Abrir cuadro de diálogo"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activar o desactivar la pantalla dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueo"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menú de accesibilidad"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> se ha incluido en el grupo de restringidos"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversación"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversación de grupo"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"+ <xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 518aa60d2bb1..196d834bb250 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Seade kustutatakse"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Administraatori rakendust ei saa kasutada. Teie seade tühjendatakse nüüd.\n\nKui teil on küsimusi, võtke ühendust organisatsiooni administraatoriga."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Rakendus <xliff:g id="OWNER_APP">%s</xliff:g> on printimise keelanud."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Isiklike rakenduste deblokeerimine"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Rakendused blokeeritakse homme"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Teie IT-administraator lubab teie tööprofiili peatada vaid kuni <xliff:g id="DAYS">%1$d</xliff:g> päevaks"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Lülitage oma tööprofiil sisse"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Teie isiklikud rakendused on blokeeritud, kuni lülitate oma tööprofiili sisse"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Teie isiklikud rakendused blokeeritakse homme"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Lülita tööprofiil sisse"</string> <string name="me" msgid="6207584824693813140">"Mina"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tahvelarvuti valikud"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Kui hoiate mõlemat helitugevuse nuppu mõni sekund all, lülitatakse sisse juurdepääsufunktsioon <xliff:g id="SERVICE">%1$s</xliff:g>. See võib teie seadme tööviisi muuta.\n\nSelle otsetee saab asendada muu otseteega jaotises Seaded > Juurdepääsetavus."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Lülita sisse"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ära lülita sisse"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SEES"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VÄLJAS"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Kas anda teenusele <xliff:g id="SERVICE">%1$s</xliff:g> teie seadme üle täielik kontroll?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Kui lülitate sisse teenuse <xliff:g id="SERVICE">%1$s</xliff:g>, ei kasuta seade andmete krüpteerimise täiustamiseks ekraanilukku."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täielik haldusõigus sobib rakendustele, mis pakuvad juurdepääsufunktsioone. Enamiku rakenduste puhul seda ei soovitata."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Administraator on seda värskendanud"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administraator on selle kustutanud"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Aku tööea pikendamiseks teeb akusäästja järgmist.\n·Lülitab sisse tumeda teema.\n·Lülitab välja taustategevused, mõned visuaalsed efektid ja muud funktsioonid (nt „Hei Google”) või piirab neid.\n\n"<annotation id="url">"Lisateave"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Aku tööea pikendamiseks teeb akusäästja järgmist.\n·Lülitab sisse tumeda teema.\n·Lülitab välja taustategevused, mõned visuaalsed efektid ja muud funktsioonid (nt „Hei Google”) või piirab neid."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Andmekasutuse vähendamiseks keelab andmemahu säästja mõne rakenduse puhul andmete taustal saatmise ja vastuvõtmise. Rakendus, mida praegu kasutate, pääseb andmesidele juurde, kuid võib seda teha väiksema sagedusega. Seetõttu võidakse näiteks pildid kuvada alles siis, kui neid puudutate."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Lülitada andmemahu säästja sisse?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Lülita sisse"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Märguanded"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Kiirseaded"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Energiasäästja dialoog"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Vaheta jagatud ekraanikuva"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lukustuskuva"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekraanipilt"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Juurdepääsetavuse menüü"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> pealkirjariba."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on lisatud salve PIIRANGUTEGA"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Vestlus"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupivestlus"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index a7777fd0270b..b8810c509322 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -200,9 +200,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Gailuko datuak ezabatu egingo dira"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Ezin da erabili administratzeko aplikazioa. Ezabatu egingo da gailuko eduki guztia.\n\nZalantzarik baduzu, jarri erakundeko administratzailearekin harremanetan."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> aplikazioak desgaitu egin du inprimatzeko aukera."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desblokeatu aplikazio pertsonalak"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Bihar blokeatuko dira aplikazioak"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IKT sailaren administratzaileak ez du onartzen laneko profila <xliff:g id="DAYS">%1$d</xliff:g> egunean baino gehiagoan pausatuta egotea"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Aktibatu laneko profila"</string> <string name="me" msgid="6207584824693813140">"Ni"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tabletaren aukerak"</string> @@ -1631,6 +1634,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Eduki sakatuta bolumen-teklak segundo batzuez <xliff:g id="SERVICE">%1$s</xliff:g> izeneko erabilerraztasun-eginbidea aktibatzeko. Honen bidez, baliteke zure mugikorraren funtzionamendua aldatzea.\n\nLasterbide hau beste eginbide batengatik aldatzeko, joan Ezarpenak > Erabilerraztasuna atalera."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktibatu"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ez aktibatu"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIBATUTA"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESAKTIBATUTA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Gailua guztiz kontrolatzeko baimena eman nahi diozu <xliff:g id="SERVICE">%1$s</xliff:g> zerbitzuari?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> aktibatzen baduzu, gailuak ez du pantailaren blokeoa erabiliko datuen enkriptatzea hobetzeko."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Erabilerraztasun-beharrak asetzen dituzten aplikazioetan da egokia kontrol osoa, baina ez aplikazio gehienetan."</string> @@ -1792,8 +1797,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Administratzaileak eguneratu du"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratzaileak ezabatu du"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Ados"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Bateriaren iraupena luzatzeko, erabili bateria-aurrezlea:\n·Gai iluna aktibatzen du\n Desaktibatu edo murriztu egiten ditu atzeko planoko jarduerak, zenbait efektu bisual eta beste eginbide batzuk, hala nola \"Ok Google\"\n\n"<annotation id="url">"Lortu informazio gehiago"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Bateriaren iraupena luzatzeko, erabili bateria-aurrezlea:\n·Gai iluna aktibatzen du\n Desaktibatu edo murriztu egiten ditu atzeko planoko jarduerak, zenbait efektu bisual eta beste eginbide batzuk, hala nola \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Datuen erabilera murrizteko, atzeko planoan datuak bidaltzea eta jasotzea galarazten die datu-aurrezleak aplikazio batzuei. Une honetan erabiltzen ari zaren aplikazioak atzitu egin ahal izango ditu datuak, baina baliteke maiztasun txikiagoarekin atzitzea. Horrela, adibidez, baliteke irudiak ez erakustea haiek sakatu arte."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Datu-aurrezlea aktibatu nahi duzu?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktibatu"</string> @@ -2038,13 +2045,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Jakinarazpenak"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Ezarpen bizkorrak"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Piztu edo itzaltzeko leihoa"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Aktibatu/Desaktibatu pantaila zatitua"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantaila blokeatua"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Pantaila-argazkia"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Erabilerraztasun-menua"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko azpitituluen barra."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Murriztuen edukiontzian ezarri da <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Elkarrizketa"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Taldeko elkarrizketa"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 474c80306bef..28254d91caa7 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"دستگاهتان پاک خواهد شد"</string> <string name="factory_reset_message" msgid="2657049595153992213">"برنامه سرپرست سیستم را نمیتوان استفاده کرد. دستگاه شما در این لحظه پاک میشود.\n\nاگر سؤالی دارید، با سرپرست سیستم سازمانتان تماس بگیرید."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> چاپ کردن را غیرفعال کرده است."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"لغو انسداد برنامههای شخصی"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"برنامهها فردا مسدود خواهند شد"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"سرپرست فناوری اطلاعات اجازه نمیدهد نمایه کاری شما بیشتر از <xliff:g id="DAYS">%1$d</xliff:g> روز بهطور موقت متوقف باشد"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"نمایه کاریتان را روشن کنید"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"تا زمانیکه نمایه کاریتان را روشن نکنید، برنامههای شخصیتان مسدود هستند"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"برنامههای شخصیتان فردا مسدود میشوند"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"روشن کردن نمایه کاری"</string> <string name="me" msgid="6207584824693813140">"من"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"گزینههای رایانهٔ لوحی"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"با پایین نگه داشتن هردو کلید میزان صدا بهمدت چند ثانیه، <xliff:g id="SERVICE">%1$s</xliff:g> (یکی از ویژگیهای دسترسپذیری) روشن میشود. با این کار نحوه عملکرد دستگاهتان تغییر میکند.\n\nمیتوانید در «تنظیمات > دسترسپذیری»،این میانبر را به ویژگی دیگری تغییر دهید."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"روشن کردن"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"روشن نشود"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"روشن"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"خاموش"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"به <xliff:g id="SERVICE">%1$s</xliff:g> اجازه میدهید بر دستگاهتان کنترل کامل داشته باشد؟"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"اگر <xliff:g id="SERVICE">%1$s</xliff:g> را روشن کنید، دستگاه شما از قفل صفحه شما جهت بهبود رمزگذاری اطلاعات استفاده نخواهد کرد."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"کنترل کامل برای بیشتر برنامهها مناسب نیست، بهجز برنامههایی که به شما در زمینه نیازهای دسترسپذیری کمک میکند."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"توسط سرپرست سیستم بهروزرسانی شد"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"توسط سرپرست سیستم حذف شد"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"تأیید"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"برای افزایش عمر باتری، «بهینهسازی باتری»:\n «طرح زمینه تیره» را روشن میکند\n فعالیت پسزمینه، برخی جلوههای بصری، و دیگر ویژگیها مانند «Ok Google» را خاموش یا محدود میکند\n\n"<annotation id="url">"بیشتر بدانید"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"برای افزایش عمر باتری، «بهینهسازی باتری»:\n «طرح زمینه تیره» را روشن میکند\n فعالیت پسزمینه، برخی جلوههای بصری، و دیگر ویژگیها مانند «Ok Google» را خاموش یا محدود میکند"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"«صرفهجویی داده»، برای کمک به کاهش مصرف داده، از ارسال و دریافت داده در پسزمینه ازطرف بعضی برنامهها جلوگیری میکند. برنامهای که درحالحاضر استفاده میکنید میتواند به دادهها دسترسی داشته باشد اما دفعات دسترسی آن محدود است.این یعنی، برای مثال، تصاویر تازمانیکه روی آنها ضربه نزنید نشان داده نمیشوند."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"«صرفهجویی داده» روشن شود؟"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"روشن کردن"</string> @@ -2009,7 +2013,7 @@ <string name="mime_type_apk" msgid="3168784749499623902">"برنامه Android"</string> <string name="mime_type_generic" msgid="4606589110116560228">"فایل"</string> <string name="mime_type_generic_ext" msgid="9220220924380909486">"<xliff:g id="EXTENSION">%1$s</xliff:g> فایل"</string> - <string name="mime_type_audio" msgid="4933450584432509875">"صدا"</string> + <string name="mime_type_audio" msgid="4933450584432509875">"صوتی"</string> <string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> صوتی"</string> <string name="mime_type_video" msgid="7071965726609428150">"ویدیو"</string> <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> ویدیو"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"اعلانها"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"تنظیمات سریع"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"کادر گفتگوی روشن/خاموش"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"تغییر وضعیت صفحهٔ دونیمه"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"صفحه قفل"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"نماگرفت"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"منوی دسترسپذیری"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"نوار شرح <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> در سطل «محدودشده» قرار گرفت"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"مکالمه"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"مکالمه گروهی"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"+<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 24693271aaa4..e7f3a9bb09f8 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Laitteen tiedot poistetaan"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Hallintasovellusta ei voi käyttää. Laitteen tiedot pyyhitään.\n\nPyydä ohjeita järjestelmänvalvojaltasi."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> on poistanut tulostuksen käytöstä."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Kumoa omien sovellusten esto"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Sovellukset estetään huomenna"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT-järjestelmänvalvoja ei anna keskeyttää työprofiiliasi yli <xliff:g id="DAYS">%1$d</xliff:g> päiväksi"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Laita työprofiilisi päälle"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Henkilökohtaiset sovelluksesi estetään, kunnes laitat työprofiilisi päälle"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Henkilökohtaiset sovelluksesi estetään huomenna"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Laita työprofiili päälle"</string> <string name="me" msgid="6207584824693813140">"Minä"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet-laitteen asetukset"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Molempien äänenvoimakkuuspainikkeiden pitkään painaminen laittaa päälle esteettömyysominaisuuden <xliff:g id="SERVICE">%1$s</xliff:g>. Tämä voi muuttaa laitteesi toimintaa.\n\nVoit muuttaa tätä pikanäppäintä kohdassa Asetukset > Esteettömyys."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Laita päälle"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Älä laita päälle"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"PÄÄLLÄ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"EI PÄÄLLÄ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Saako <xliff:g id="SERVICE">%1$s</xliff:g> laitteesi täyden käyttöoikeuden?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jos <xliff:g id="SERVICE">%1$s</xliff:g> otetaan käyttöön, laitteesi ei käytä näytön lukitusta tiedon salauksen parantamiseen."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täysi käyttöoikeus sopii esteettömyyssovelluksille, mutta ei useimmille sovelluksille."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Järjestelmänvalvoja päivitti tämän."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Parantaakseen akunkestoa virransäästö\n·ottaa tumman teeman käyttöön\n·poistaa käytöstä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Hei Google).\n\n"<annotation id="url">"Lue lisää"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Parantaakseen akunkestoa virransäästö\n·ottaa tumman teeman käyttöön\n·poistaa käytöstä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Hei Google)."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Data Saver estää joitakin sovelluksia lähettämästä tai vastaanottamasta tietoja taustalla, jotta datan käyttöä voidaan vähentää. Käytössäsi oleva sovellus voi yhä käyttää dataa, mutta se saattaa tehdä niin tavallista harvemmin. Tämä voi tarkoittaa esimerkiksi sitä, että kuva ladataan vasta, kun kosketat sitä."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Otetaanko Data Saver käyttöön?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ota käyttöön"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Ilmoitukset"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Pika-asetukset"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Virran valintaikkuna"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Jaettu näyttö päälle/pois"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lukitusnäyttö"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Kuvakaappaus"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Esteettömyysvalikko"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Tekstityspalkki: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on nyt rajoitettujen ryhmässä"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Keskustelu"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Ryhmäkeskustelu"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 515637d1366e..9a6f186056d6 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Le contenu de votre appareil sera effacé"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, communiquez avec l\'administrateur de votre organisation."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Débloquer applis personnelles"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Les applis seront bloquées demain"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Votre administrateur informatique ne vous permet pas d\'interrompre le profil professionnel pendant plus de <xliff:g id="DAYS">%1$d</xliff:g> jours"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activer profil professionnel"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vos applications personnelles sont bloquées jusqu\'à ce que vous activiez votre profil professionnel"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Vos applications personnelles seront bloquées demain"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Activer le profil professionnel"</string> <string name="me" msgid="6207584824693813140">"Moi"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Options de la tablette"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Si vous maintenez enfoncées les deux touches de volume pendant quelques secondes, vous activez la fonctionnalité d\'accessibilité <xliff:g id="SERVICE">%1$s</xliff:g>. Cela peut modifier le fonctionnement de votre appareil.\n\nPour attribuer ce raccourci à une autre fonctionnalité, sélectionnez Paramètres > Accessibilité."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activer"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ne pas activer"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVÉ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permettre à <xliff:g id="SERVICE">%1$s</xliff:g> de commander complètement votre appareil?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si vous activez <xliff:g id="SERVICE">%1$s</xliff:g>, votre appareil n\'utilisera pas le verrouillage de l\'écran pour améliorer le chiffrement des données."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des applications."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Mise à jour par votre administrateur"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Pour prolonger l\'autonomie de la pile, l\'économiseur de pile effectue les actions suivantes :\n·Activer le thème sombre\n·Désactiver ou limiter l\'activité en arrière-plan, certains effets visuels et d\'autres fonctionnalités, comme « Ok Google »\n\n"<annotation id="url">"En savoir plus"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Pour prolonger l\'autonomie de la pile, l\'économiseur de pile effectue les actions suivantes :\n·Active le thème sombre\n·Désactive ou limite l\'activité en arrière-plan, certains effets visuels et d\'autres fonctionnalités, comme « Ok Google »"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Pour aider à diminuer l\'utilisation des données, la fonctionnalité Économiseur de données empêche certaines applications d\'envoyer ou de recevoir des données en arrière-plan. Une application que vous utilisez actuellement peut accéder à des données, mais peut le faire moins souvent. Cela peut signifier, par exemple, que les images ne s\'affichent pas jusqu\'à ce que vous les touchiez."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Activer l\'économiseur de données?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Paramètres rapides"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Boîte de dialogue sur l\'alimentation"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Basculer l\'écran partagé"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Écran de verrouillage"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capture d\'écran"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu d\'accessibilité"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barre de légende de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le compartiment RESTREINT"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversation de groupe"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 86facd466c42..75fc6671fdfb 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Les données de votre appareil vont être effacées"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, contactez l\'administrateur de votre organisation."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Débloquez vos applis perso"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Applis seront bloquées demain"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Votre administrateur informatique ne vous autorise pas à mettre en pause votre profil professionnel pendant plus de <xliff:g id="DAYS">%1$d</xliff:g> jours"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activez profil professionnel"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vos applications personnelles sont bloquées jusqu\'à ce que vous activiez votre profil professionnel"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Vos applications personnelles seront bloquées demain"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Activer le profil professionnel"</string> <string name="me" msgid="6207584824693813140">"Moi"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Options de la tablette"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Si vous appuyez sur les deux touches de volume pendant quelques secondes, vous activez la fonctionnalité d\'accessibilité <xliff:g id="SERVICE">%1$s</xliff:g>. Cela peut affecter le fonctionnement de votre appareil.\n\nPour attribuer ce raccourci à une autre fonctionnalité, accédez à Paramètres > Accessibilité."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activer"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ne pas activer"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVÉE"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉE"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Accorder le contrôle total de votre appareil au service <xliff:g id="SERVICE">%1$s</xliff:g> ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si vous activez <xliff:g id="SERVICE">%1$s</xliff:g>, votre appareil n\'utilisera pas le verrouillage de l\'écran pour améliorer le chiffrement des données."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des applications."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Mis à jour par votre administrateur"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Pour prolonger l\'autonomie de la batterie, l\'économiseur de batterie :\n· active le thème sombre ;\n· désactive ou restreint les activités en arrière-plan, certains effets visuels et d\'autres fonctionnalités, comme \"Ok Google\".\n\n"<annotation id="url">"En savoir plus"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Pour prolonger l\'autonomie de la batterie, l\'économiseur de batterie :\n· active le thème sombre ;\n· désactive ou restreint les activités en arrière-plan, certains effets visuels et d\'autres fonctionnalités, comme \"Ok Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Pour réduire la consommation de données, l\'économiseur de données empêche certaines applications d\'envoyer ou de recevoir des données en arrière-plan. Ainsi, les applications que vous utilisez peuvent toujours accéder aux données, mais pas en permanence. Par exemple, il se peut que les images ne s\'affichent pas tant que vous n\'appuyez pas dessus."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Activer l\'économiseur de données ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Configuration rapide"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Boîte de dialogue Marche/Arrêt"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activer/Désactiver l\'écran partagé"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Verrouiller l\'écran"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capture d\'écran"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu d\'accessibilité"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barre de légende de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le bucket RESTRICTED"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversation de groupe"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g> ou +"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index c7cdd1351e05..a475b41b5819 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -200,9 +200,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Borrarase o teu dispositivo"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Non se pode utilizar a aplicación de administración. Borrarase o teu dispositivo.\n\nSe tes preguntas, contacta co administrador da organización."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> desactivou a impresión."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desbloquea as apps persoais"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"As apps bloquearanse mañá"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"O teu administrador de TI non permite que o teu perfil de traballo se poña en pausa máis de <xliff:g id="DAYS">%1$d</xliff:g> días"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Activar perfil de traballo"</string> <string name="me" msgid="6207584824693813140">"Eu"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcións da tableta"</string> @@ -1631,6 +1634,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ao manter as dúas teclas de volume premidas durante uns segundos actívase <xliff:g id="SERVICE">%1$s</xliff:g>, unha función de accesibilidade. Esta acción pode cambiar o funcionamento do dispositivo.\n\nPodes cambiar o uso deste atallo para outra función en Configuración > Accesibilidade."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activar"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Non activar"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SI"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NON"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Queres permitir que <xliff:g id="SERVICE">%1$s</xliff:g> poida controlar totalmente o teu dispositivo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se activas <xliff:g id="SERVICE">%1$s</xliff:g>, o dispositivo non utilizará o teu bloqueo de pantalla para mellorar a encriptación de datos."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O control total é adecuado para as aplicacións que che axudan coa accesibilidade, pero non para a maioría das aplicacións."</string> @@ -1792,8 +1797,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado polo teu administrador"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado polo teu administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Para aumentar a duración da batería, a función Aforro de batería fai o seguinte:\n·Activa o tema escuro\n·Desactiva ou restrinxe a actividade en segundo plano, algúns efectos visuais e outras funcións, como \"Ok Google\"\n\n"<annotation id="url">"Máis información"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Para aumentar a duración da batería, a función Aforro de batería fai o seguinte:\n·Activa o tema escuro\n·Desactiva ou restrinxe a actividade en segundo plano, algúns efectos visuais e outras funcións, como \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Para contribuír a reducir o uso de datos, o aforro de datos impide que algunhas aplicacións envíen ou reciban datos en segundo plano. Cando esteas utilizando unha aplicación, esta poderá acceder aos datos, pero é posible que o faga con menos frecuencia. Por exemplo, é posible que as imaxes non se mostren ata que as toques."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Queres activar o aforro de datos?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string> @@ -2038,13 +2045,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificacións"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Configuración rápida"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Cadro de diálogo de acendido/apagado"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activar/desactivar pantalla dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueo"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menú de accesibilidade"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> incluíuse no grupo RESTRINXIDO"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversa"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversa de grupo"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"><xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index c35b7e6ca0c0..b6ea39a0c23c 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"તમારું ઉપકરણ કાઢી નાખવામાં આવશે"</string> <string name="factory_reset_message" msgid="2657049595153992213">"વ્યવસ્થાપક ઍપનો ઉપયોગ કરી શકાશે નહીં. તમારું ઉપકરણ હવે કાઢી નાખવામાં આવશે.\n\nજો તમને પ્રશ્નો હોય, તો તમારી સંસ્થાના વ્યવસ્થાપકનો સંપર્ક કરો."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> દ્વારા પ્રિન્ટ કરવાનું બંધ કરાયું છે."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"તમારી ખાનગી ઍપને અનબ્લૉક કરો"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ઍપ આવતીકાલે બ્લૉક કરાશે"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"તમારા IT વ્યવસ્થાપક તમારી કાર્યાલયની પ્રોફાઇલને <xliff:g id="DAYS">%1$d</xliff:g>થી વધુ દિવસ થોભાવી રાખવાની મંજૂરી આપતા નથી"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"કાર્યાલયની પ્રોફાઇલ ચાલુ કરો"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"જ્યાં સુધી તમે કાર્યાલયની પ્રોફાઇલ ચાલુ ન કરો ત્યાં સુધી તમારી વ્યક્તિગત ઍપ બ્લૉક કરેલી રહે છે"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"તમારી વ્યક્તિગત ઍપ આવતી કાલે બ્લૉક કરવામાં આવશે"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"કાર્યાલયની પ્રોફાઇલ ચાલુ કરો"</string> <string name="me" msgid="6207584824693813140">"હું"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ટેબ્લેટ વિકલ્પો"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"બન્ને વૉલ્યૂમ કીને થોડી સેકન્ડ સુધી દબાવી રાખવાથી ઍક્સેસિબિલિટી સુવિધા એવી <xliff:g id="SERVICE">%1$s</xliff:g> ચાલુ થઈ જાય છે. આનાથી તમારા ડિવાઇસની કામ કરવાની રીત બદલાઈ શકે છે.\n\nતમે સેટિંગ > ઍક્સેસિબિલિટીમાં જઈને આ શૉર્ટકટને બીજી સુવિધામાં બદલી શકો છો."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ચાલુ કરો"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ચાલુ કરશો નહીં"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ચાલુ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"બંધ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"શું <xliff:g id="SERVICE">%1$s</xliff:g>ને તમારા ડિવાઇસના સંપૂર્ણ નિયંત્રણની મંજૂરી આપીએ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"જો તમે <xliff:g id="SERVICE">%1$s</xliff:g> ચાલુ કરશો, તો તમારું ડિવાઇસ ડેટા એન્ક્રિપ્શનને બહેતર બનાવવા તમારા સ્ક્રીન લૉકનો ઉપયોગ કરશે નહીં."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ઍક્સેસિબિલિટી સંબંધિત આવશ્યકતા માટે સહાય કરતી ઍપ માટે સંપૂર્ણ નિયંત્રણ યોગ્ય છે, પણ મોટા ભાગની ઍપ માટે યોગ્ય નથી."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ કરવામાં આવેલ છે"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખવામાં આવેલ છે"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ઓકે"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"બૅટરીની આવરદા વધારવા માટે, બૅટરી સેવર:\n·ઘેરી થીમ ચાલુ કરે છે\n·બૅકગ્રાઉન્ડ પ્રવૃત્તિ, અમુક વિઝ્યુઅલ ઇફેક્ટ અને “હેય Google” જેવી અન્ય સુવિધાઓ બંધ અથવા પ્રતિબંધિત કરે છે\n\n"<annotation id="url">"વધુ જાણો"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"બૅટરીની આવરદા વધારવા માટે, બૅટરી સેવર:\n·ઘેરી થીમ ચાલુ કરે છે\n·બૅકગ્રાઉન્ડ પ્રવૃત્તિ, અમુક વિઝ્યુઅલ ઇફેક્ટ અને “હેય Google” જેવી અન્ય સુવિધાઓ બંધ અથવા પ્રતિબંધિત કરે છે"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ડેટા વપરાશને ઘટાડવામાં સહાય માટે, ડેટા સેવર કેટલીક ઍપને બૅકગ્રાઉન્ડમાં ડેટા મોકલવા અથવા પ્રાપ્ત કરવાથી અટકાવે છે. તમે હાલમાં ઉપયોગ કરી રહ્યાં છો તે ઍપ ડેટાને ઍક્સેસ કરી શકે છે, પરંતુ તે આ ક્યારેક જ કરી શકે છે. આનો અર્થ એ હોઈ શકે છે, ઉદાહરણ તરીકે, છબીઓ ત્યાં સુધી પ્રદર્શિત થશે નહીં જ્યાં સુધી તમે તેને ટૅપ નહીં કરો."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ડેટા સેવર ચાલુ કરીએ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ચાલુ કરો"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"નોટિફિકેશન"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ઝડપી સેટિંગ"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"પાવર સંવાદ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"સ્ક્રીનને વિભાજિત કરવાની ક્રિયા ટૉગલ કરો"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"લૉક સ્ક્રીન"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"સ્ક્રીનશૉટ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ઍક્સેસિબિલિટી મેનૂ"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>નું કૅપ્શન બાર."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ને પ્રતિબંધિત સમૂહમાં મૂકવામાં આવ્યું છે"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"વાતચીત"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ગ્રૂપ વાતચીત"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 5c38284cf150..6116c5a1f81e 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"आपके डिवाइस को मिटा दिया जाएगा"</string> <string name="factory_reset_message" msgid="2657049595153992213">"एडमिन ऐप्लिकेशन का इस्तेमाल नहीं किया जा सकता. आपके डिवाइस पर मौजूद डेटा अब मिटा दिया जाएगा.\n\nअगर आप कुछ पूछना चाहते हैं तो, अपने संगठन के एडमिन से संपर्क करें."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ने प्रिंटिंग सुविधा बंद कर दी है."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"अपने निजी ऐप अनब्लॉक करें"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ऐप कल ब्लॉक कर दिए जाएंगे"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"आपका आईटी एडमिन आपकी वर्क प्रोफ़ाइल को <xliff:g id="DAYS">%1$d</xliff:g> दिनों से ज़्यादा रोकने की अनुमति नहीं देता"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"अपनी वर्क प्रोफ़ाइल चालू करें"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"निजी ऐप्लिकेशन अनब्लॉक करने के लिए, अपनी वर्क प्रोफ़ाइल चालू करें"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"आपके निजी ऐप्लिकेशन कल ब्लॉक कर दिए जाएंगे"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"वर्क प्रोफ़ाइल चालू करें"</string> <string name="me" msgid="6207584824693813140">"मैं"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"टैबलेट विकल्प"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"आवाज़ कम और ज़्यादा करने वाले दोनों बटन को कुछ सेकंड तक दबाकर रखने से <xliff:g id="SERVICE">%1$s</xliff:g> चालू हो जाती है, जो एक सुलभता सुविधा है. ऐसा करने से आपके डिवाइस के काम करने के तरीके में बदलाव हो सकता है.\n\nआप सेटिंग और सुलभता में जाकर इस शॉर्टकट को किसी दूसरी सुविधा के लिए बदल सकते हैं."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"चालू करें"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"चालू न करें"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"चालू है"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"बंद है"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> को अपना डिवाइस पूरी तरह कंट्रोल करने की मंज़ूरी दें?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"अगर आप <xliff:g id="SERVICE">%1$s</xliff:g> को चालू करते हैं, तो डेटा को एन्क्रिप्ट (सुरक्षित) करने के तरीके को बेहतर बनाने के लिए आपका डिवाइस सेट किए गए स्क्रीन लॉक का इस्तेमाल नहीं करेगा."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"पूरी तरह नियंत्रित करने की अनुमति उन ऐप्लिकेशन के लिए ठीक है जो सुलभता से जुड़ी ज़रूरतों के लिए बने हैं, लेकिन ज़्यादातर ऐप्लिकेशन के लिए यह ठीक नहीं है."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"आपके व्यवस्थापक ने अपडेट किया है"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"आपके व्यवस्थापक ने हटा दिया है"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ठीक है"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"बैटरी लाइफ़ बढ़ाने के लिए बैटरी सेवर:\n·गहरे रंग वाली थीम चालू करता है\n·बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और \"Hey Google\" जैसी दूसरी सुविधाएं इस्तेमाल करने से रोकता है या बंद करता है\n\n"<annotation id="url">"ज़्यादा जानें"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"बैटरी लाइफ़ बढ़ाने के लिए, बैटरी सेवर:\n गहरे रंग वाली थीम चालू करता है\nबैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और \"Hey Google\" जैसी दूसरी सुविधाओं को रोकता या बंद करता है"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"डेटा खर्च को कम करने के लिए, डेटा सेवर कुछ ऐप्लिकेशन को बैकग्राउंड में डेटा भेजने या डेटा पाने से रोकता है. फ़िलहाल, आप जिस ऐप्लिकेशन का इस्तेमाल कर रहे हैं वह डेटा ऐक्सेस कर सकता है, लेकिन ऐसा कभी-कभी ही हो पाएगा. उदाहरण के लिए, इमेज तब तक दिखाई नहीं देंगी जब तक कि आप उन पर टैप नहीं करते."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"डेटा बचाने की सेटिंग चालू करें?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"चालू करें"</string> @@ -1806,7 +1810,7 @@ <item quantity="other">%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item> </plurals> <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758"> - <item quantity="one">%1$d घंटों के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item> + <item quantity="one">%1$d घंटे के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item> <item quantity="other">%1$d घंटों के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item> </plurals> <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642"> @@ -1822,7 +1826,7 @@ <item quantity="other">%d मिनट के लिए</item> </plurals> <plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022"> - <item quantity="one">%d घंटों के लिए</item> + <item quantity="one">%d घंटे के लिए</item> <item quantity="other">%d घंटों के लिए</item> </plurals> <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640"> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"सूचनाएं खोलें"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"फटाफट सेटिंग खोलें"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"पावर डायलॉग खोलें"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"स्प्लिट स्क्रीन पर टॉगल करें"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"स्क्रीन लॉक करें"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रीनशॉट लें"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"सुलभता मेन्यू"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> का कैप्शन बार."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> को प्रतिबंधित बकेट में रखा गया है"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"बातचीत"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ग्रुप में बातचीत"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index a7ae6862fcdc..811df8fbafdc 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -202,9 +202,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će se izbrisati"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Administratorska aplikacija ne može se upotrebljavati. Uređaj će se izbrisati.\n\nAko imate pitanja, obratite se administratoru organizacije."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Ispis je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Deblokiranje osob. aplikacija"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Sutra se blokiraju aplikacije"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Vaš IT administrator ne dopušta pauziranje poslovnog profila dulje od <xliff:g id="DAYS">%1$d</xliff:g> dana"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Uključite poslovni profil"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vaše su osobne aplikacije blokirane dok ne uključite poslovni profil"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Vaše će se osobne aplikacije sutra blokirati"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Uključi poslovni profil"</string> <string name="me" msgid="6207584824693813140">"Ja"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcije tabletnog uređaja"</string> @@ -1653,6 +1653,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ako na nekoliko sekundi pritisnete obje tipke za glasnoću, uključuje se značajka pristupačnosti <xliff:g id="SERVICE">%1$s</xliff:g>. Time se može promijeniti način na koji vaš uređaj radi.\n\nZnačajku na koju se taj prečac odnosi možete promijeniti u odjeljku Postavke > Pristupačnost."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Uključi"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nemoj uključiti"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"UKLJUČENO"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ISKLJUČENO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Želite li dopustiti usluzi <xliff:g id="SERVICE">%1$s</xliff:g> potpunu kontrolu nad uređajem?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ako uključite <xliff:g id="SERVICE">%1$s</xliff:g>, vaš uređaj neće upotrebljavati zaključavanje zaslona za bolju enkripciju podataka."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Potpuna kontrola prikladna je za aplikacije koje vam pomažu s potrebama pristupačnosti, ali ne i za većinu aplikacija."</string> @@ -1815,8 +1817,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao administrator"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"U redu"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Da bi se produljilo trajanje baterije, Štednja baterije:\n·Uključuje Tamnu temu.\n·Isključuje ili ograničava aktivnosti u pozadini, neke vizualne efekte i druge značajke kao što je \"Hey Google\".\n\n"<annotation id="url">"Saznajte više"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Da bi se produljilo trajanje baterije, Štednja baterije:\n·uključuje Tamnu temu\n·isključuje ili ograničava aktivnosti u pozadini, neke vizualne efekte i druge značajke kao što je \"Hey Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjio podatkovni promet, značajka Štednja podatkovnog prometa onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti Štednju podatkovnog prometa?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string> @@ -2072,13 +2076,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obavijesti"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brze postavke"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijalog napajanja"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Uključite ili isključite podijeljeni zaslon"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključajte zaslon"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimka zaslona"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Izbornik pristupačnosti"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka naslova aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> premješten je u spremnik OGRANIČENO"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Razgovor"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupni razgovor"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 179531530f97..26f7584311a9 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"A rendszer törölni fogja eszközét"</string> <string name="factory_reset_message" msgid="2657049595153992213">"A rendszergazdai alkalmazás nem használható. A rendszer most törli az eszközt.\n\nKérdéseivel forduljon szervezete rendszergazdájához."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"A(z) <xliff:g id="OWNER_APP">%s</xliff:g> letiltotta a nyomtatást."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"A személyes appok feloldása"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Appok feloldása holnap"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Rendszergazdája nem engedélyezi, hogy a munkaprofil <xliff:g id="DAYS">%1$d</xliff:g> napnál tovább szüneteltetve legyen"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Munkaprofil bekapcsolása"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"A személyes alkalmazások le lesznek tiltva, amíg be nem kapcsolja a munkaprofilt"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Személyes alkalmazásai holnap lesznek letiltva"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Munkaprofil bekapcsolása"</string> <string name="me" msgid="6207584824693813140">"Saját"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Táblagép beállításai"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"A(z) <xliff:g id="SERVICE">%1$s</xliff:g> kisegítő lehetőség bekapcsolásához tartsa nyomva néhány másodpercig mindkét hangerőgombot. Ez hatással lehet az eszköz működésére.\n\nEzt a gyorsparancsot a Beállítások > Kisegítő lehetőségek pontban módosíthatja másik funkció használatára."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Bekapcsolás"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nem kapcsolom be"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"BE"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"KI"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Teljes körű vezérlést biztosít eszköze felett a(z) <xliff:g id="SERVICE">%1$s</xliff:g> szolgáltatás számára?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ha engedélyezi a(z) <xliff:g id="SERVICE">%1$s</xliff:g> szolgáltatást, az eszköz nem fogja használni a képernyőzárat az adattitkosítás növelése érdekében."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"A teljes vezérlés indokolt olyan alkalmazásoknál, amelyek kisegítő lehetőségeket nyújtanak, a legtöbb alkalmazásnál azonban nem."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"A rendszergazda által frissítve"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"A rendszergazda által törölve"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Az Akkumulátorkímélő mód az akkumulátor üzemidejének növelése érdekében a következőket teszi:\n Bekapcsolja a sötét témát.\n Kikapcsolja vagy korlátozza a háttérben futó tevékenységeket, egyes vizuális effekteket, az „Ok Google” parancsot és egyéb funkciókat.\n\n"<annotation id="url">"További információ"</annotation>"."</string> - <string name="battery_saver_description" msgid="7618492104632328184">"Az Akkumulátorkímélő mód az akkumulátor üzemidejének növelése érdekében a következőket teszi:\n Bekapcsolja a sötét témát.\n Kikapcsolja vagy korlátozza a háttérben futó tevékenységeket, egyes vizuális effekteket, az „Ok Google” parancsot és egyéb funkciókat."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Az adatforgalom csökkentése érdekében az Adatforgalom-csökkentő megakadályozza, hogy egyes alkalmazások adatokat küldjenek vagy fogadjanak a háttérben. Az Ön által jelenleg használt alkalmazások hozzáférhetnek az adatokhoz, de csak ritkábban. Ez például azt jelentheti, hogy a képek csak rákoppintás után jelennek meg."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Bekapcsolja az Adatforgalom-csökkentőt?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Bekapcsolás"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Értesítések"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Gyorsbeállítások"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Akkumulátorral kapcsolatos párbeszédpanel"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Osztott képernyő be- vagy kikapcsolása"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lezárási képernyő"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Képernyőkép"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Kisegítő lehetőségek menü"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás címsora."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"A következő csomag a KORLÁTOZOTT csoportba került: <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Beszélgetés"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Csoportos beszélgetés"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 1ba41b313030..d7d00f200a6d 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -200,9 +200,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Ձեր սարքը ջնջվելու է"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Հնարավոր չէ օգտագործել ադմինիստրատորի հավելվածը։ Ձեր սարքից բոլոր տվյալները կջնջվեն։\n\nՀարցեր ունենալու դեպքում դիմեք ձեր կազմակերպության ադմինիստրատորին։"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Տպումն անջատված է <xliff:g id="OWNER_APP">%s</xliff:g> հավելվածի կողմից։"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Արգելաբացեք անձնական հավելվածները"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Հավելվածները վաղը կարգելափակվեն"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Ձեր ՏՏ ադմինիստրատորը չի թույլատրում <xliff:g id="DAYS">%1$d</xliff:g> օրից ավել դադարեցնել աշխատանքային պրոֆիլը։"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Միացնել աշխատանքային պրոֆիլը"</string> <string name="me" msgid="6207584824693813140">"Իմ"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Պլանշետի ընտրանքները"</string> @@ -1403,8 +1406,8 @@ <string name="ime_action_default" msgid="8265027027659800121">"Կատարել"</string> <string name="dial_number_using" msgid="6060769078933953531">"Հավաքել հեռախոսահամարը`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string> <string name="create_contact_using" msgid="6200708808003692594">"Ստեղծել կոնտակտ`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string> - <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Հետևյալ մեկ կամ ավել հավելվածներ մուտքի թույլտվության հարցում են անում` այժմ և հետագայում ձեր հաշվին մուտք ունենալու համար:"</string> - <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Ցանկանու՞մ եք թույլատրել այս հարցումը:"</string> + <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Հետևյալ մեկ կամ մի քանի հավելվածներին թույլտվություն է անհրաժեշտ՝ այժմ և հետագայում ձեր հաշվի տվյալներն օգտագործելու համար։"</string> + <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Թույլատրե՞լ"</string> <string name="grant_permissions_header_text" msgid="3420736827804657201">"Մուտքի հարցում"</string> <string name="allow" msgid="6195617008611933762">"Թույլատրել"</string> <string name="deny" msgid="6632259981847676572">"Մերժել"</string> @@ -1631,6 +1634,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ձայնի կարգավորման երկու կոճակները մի քանի վայրկյան սեղմած պահելով կմիացնեք <xliff:g id="SERVICE">%1$s</xliff:g> ծառայությունը, որը հատուկ գործառույթ է։ Դրա արդյունքում սարքի աշխատաեղանակը կարող է փոխվել։\n\nԱյս դյուրանցումը մեկ այլ գործառույթով փոխելու համար անցեք Կարգավորումներ > Հատուկ գործառույթներ։"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Միացնել"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Չմիացնել"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ՄԻԱՑՎԱԾ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ԱՆՋԱՏՎԱԾ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Թույլատրե՞լ <xliff:g id="SERVICE">%1$s</xliff:g> ծառայությանը կառավարել ձեր սարքը"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Եթե միացնեք <xliff:g id="SERVICE">%1$s</xliff:g> ծառայությունը, ձեր սարքը չի օգտագործի էկրանի կողպումը՝ տվյալների գաղտնագրումը բարելավելու համար:"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Ամբողջական վերահսկումն անհրաժեշտ է միայն այն հավելվածներին, որոնք օգնում են ձեզ հատուկ գործառույթներից օգտվելիս։"</string> @@ -1792,8 +1797,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Թարմացվել է ձեր ադմինիստրատորի կողմից"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Ջնջվել է ձեր ադմինիստրատորի կողմից"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Եղավ"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Մարտկոցի աշխատաժամանակը երկարացնելու համար «Մարտկոցի տնտեսում» գործառույթը\n·միացնում է մուգ թեման,\n·անջատում կամ սահմանափակում է աշխատանքը ֆոնային ռեժիմում, որոշ վիզուալ էֆեկտներ և այլ գործառույթներ, օրինակ «OK Google» հրահանգը:\n\n"<annotation id="url">"Իմանալ ավելին"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Մարտկոցի աշխատաժամանակը երկարացնելու համար «Մարտկոցի տնտեսում» գործառույթը\n·միացնում է մուգ թեման,\n·անջատում կամ սահմանափակում է աշխատանքը ֆոնային ռեժիմում, որոշ վիզուալ էֆեկտներ և այլ գործառույթներ, օրինակ «OK Google» հրահանգը:"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Թրաֆիկի տնտեսման ռեժիմում որոշ հավելվածների համար տվյալների ֆոնային փոխանցումն անջատված է։ Հավելվածը, որն օգտագործում եք, կարող է տվյալներ փոխանցել և ստանալ, սակայն ոչ այնքան հաճախ: Օրինակ՝ պատկերները կցուցադրվեն միայն դրանց վրա սեղմելուց հետո։"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Միացնե՞լ թրաֆիկի խնայումը:"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Միացնել"</string> @@ -2038,13 +2045,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Ծանուցումներ"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Արագ կարգավորումներ"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Սնուցման պատուհան"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Միացնել/անջատել էկրանի տրոհումը"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Կողպէկրան"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Սքրինշոթ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Հատուկ գործառույթների ընտրացանկ"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի ենթագրերի գոտին։"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> փաթեթը գցվեց ՍԱՀՄԱՆԱՓԱԿՎԱԾ զամբյուղի մեջ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>՝"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Նամակագրություն"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Խմբային նամակագրություն"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 338471d89a51..458df3b3ee92 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Perangkat akan dihapus"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Aplikasi admin tidak dapat digunakan. Perangkat Anda kini akan dihapus.\n\nJika ada pertanyaan, hubungi admin organisasi."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Fitur pencetakan dinonaktifkan oleh <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Batalkan pemblokiran aplikasi pribadi"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Aplikasi akan diblokir besok"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Admin IT tidak mengizinkan profil kerja Anda dijeda selama lebih dari <xliff:g id="DAYS">%1$d</xliff:g> hari"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Aktifkan profil kerja Anda"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Aplikasi pribadi Anda diblokir hingga Anda mengaktifkan profil kerja Anda"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Aplikasi kerja Anda akan diblokir besok"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Aktifkan profil kerja"</string> <string name="me" msgid="6207584824693813140">"Saya"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opsi tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Menahan kedua tombol volume selama beberapa detik akan mengaktifkan <xliff:g id="SERVICE">%1$s</xliff:g>, yang merupakan fitur aksesibilitas. Tindakan ini dapat mengubah cara kerja perangkat Anda.\n\nAnda dapat mengubah pintasan ini ke fitur lain di Setelan > Aksesibilitas."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktifkan"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Jangan aktifkan"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIF"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NONAKTIF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Izinkan <xliff:g id="SERVICE">%1$s</xliff:g> memiliki kontrol penuh atas perangkat Anda?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jika Anda mengaktifkan <xliff:g id="SERVICE">%1$s</xliff:g>, perangkat tidak akan menggunakan kunci layar untuk meningkatkan enkripsi data."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrol penuh sesuai untuk aplikasi yang membantu Anda terkait kebutuhan aksesibilitas, tetapi tidak untuk sebagian besar aplikasi."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Diupdate oleh admin Anda"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dihapus oleh admin Anda"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Oke"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Untuk memperpanjang masa pakai baterai, Penghemat Baterai:\n·Mengaktifkan Tema gelap\n·Menonaktifkan atau membatasi aktivitas di latar belakang, beberapa efek visual, dan fitur lain seperti “Ok Google”\n\n"<annotation id="url">"Pelajari lebih lanjut"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Untuk memperpanjang masa pakai baterai, Penghemat Baterai:\n·Mengaktifkan Tema gelap\n·Menonaktifkan atau membatasi aktivitas di latar belakang, beberapa efek visual, dan fitur lain seperti “Ok Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Untuk membantu mengurangi penggunaan data, Penghemat Data mencegah beberapa aplikasi mengirim atau menerima data di latar belakang. Aplikasi yang sedang digunakan dapat mengakses data, tetapi frekuensinya agak lebih jarang. Misalnya saja, gambar hanya akan ditampilkan setelah diketuk."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Aktifkan Penghemat Data?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktifkan"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifikasi"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Setelan Cepat"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialog Daya"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Aktifkan/Nonaktifkan Layar Terpisah"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Layar Kunci"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu Aksesibilitas"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Kolom teks <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah dimasukkan ke dalam bucket DIBATASI"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Percakapan"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Percakapan Grup"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 6c017e83adf7..fa03fbab425a 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Tækið verður hreinsað"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Ekki er hægt að nota stjórnunarforritið. Tækinu verður eytt.\n\nEf spurningar vakna skaltu hafa samband við kerfisstjóra fyrirtækisins."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> lokaði á prentun."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Opna fyrir persónuleg forrit"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Lokað á forrit á morgun"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Kerfisstjórinn þinn leyfir ekki að hlé sé gert á vinnusniði lengur en í <xliff:g id="DAYS">%1$d</xliff:g> daga"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Kveiktu á vinnusniði"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Lokað er á forrit til einkanota þar til þú kveikir á vinnusniði"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Lokað verður á forrit til einkanota á morgun"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Kveikja á vinnusniði"</string> <string name="me" msgid="6207584824693813140">"Ég"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Valkostir spjaldtölvu"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ef báðum hljóðstyrkstökkunum er haldið inni í nokkrar sekúndur er kveikt á aðgengiseiginleikanum <xliff:g id="SERVICE">%1$s</xliff:g>. Þetta getur breytt því hvernig tækið virkar.\n\nÞú getur breytt þessari flýtileið í annan eiginleika í Stillingar > Aðgengi."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Kveikja"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ekki kveikja"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"KVEIKT"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"SLÖKKT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Viltu leyfa <xliff:g id="SERVICE">%1$s</xliff:g> að hafa fulla stjórn yfir tækinu þínu?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ef þú kveikir á <xliff:g id="SERVICE">%1$s</xliff:g> mun tækið ekki nota skjálásinn til að efla dulkóðun gagna."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full stjórnun er viðeigandi fyrir forrit sem hjálpa þér ef þú hefur ekki aðgang, en ekki fyrir flest forrit."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Kerfisstjóri uppfærði"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Kerfisstjóri eyddi"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Í lagi"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Til að auka rafhlöðuendingu gerir rafhlöðusparnaður eftirfarandi:\n·Kveikir á dökku þema\n·Slekkur á eða takmarkar bakgrunnsvirkni, tilteknar myndbrellur og aðra eiginleika eins og „Ok Google“.\n\n"<annotation id="url">"Frekari upplýsingar"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Til að auka rafhlöðuendingu gerir rafhlöðusparnaður eftirfarandi:\n·Kveikir á dökku þema\n·Slekkur á eða takmarkar bakgrunnsvirkni, tilteknar myndbrellur og aðra eiginleika eins og „Ok Google“."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Gagnasparnaður getur hjálpað til við að draga úr gagnanotkun með því að hindra forrit í að senda eða sækja gögn í bakgrunni. Forrit sem er í notkun getur náð í gögn, en gerir það kannski sjaldnar. Niðurstaðan getur verið, svo dæmi sé tekið, að myndir eru ekki birtar fyrr en þú ýtir á þær."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Kveikja á gagnasparnaði?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Kveikja"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Tilkynningar"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Flýtistillingar"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Gluggi til að slökkva/endurræsa"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Breyta skjáskiptingu"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lásskjár"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjámynd"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Aðgengisvalmynd"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Skjátextastika <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> var sett í flokkinn TAKMARKAÐ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Samtal"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Hópsamtal"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index ed0a6bcbb0ee..1ed81f1054a9 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Il dispositivo verrà resettato"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Impossibile usare l\'app di amministrazione. Il dispositivo verrà resettato.\n\nPer eventuali domande, contatta l\'amministratore della tua organizzazione."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Stampa disattivata da <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Sblocca le tue app personali"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"App saranno bloccate domani"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"L\'amministratore IT non consente di sospendere il profilo di lavoro per più di <xliff:g id="DAYS">%1$d</xliff:g> giorni"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Attiva il profilo di lavoro"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Le tue app personali sono bloccate fino all\'attivazione del tuo profilo di lavoro"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Le tue app personali verranno bloccate domani"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Attiva profilo di lavoro"</string> <string name="me" msgid="6207584824693813140">"Io"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opzioni tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Se tieni premuti entrambi i tasti del volume per qualche secondo verrà attivata la funzione di accessibilità <xliff:g id="SERVICE">%1$s</xliff:g>. Questa operazione potrebbe modificare il funzionamento del dispositivo.\n\nPuoi associare questa scorciatoia a un\'altra funzionalità in Impostazioni > Accessibilità."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Attiva"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Non attivare"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vuoi consentire a <xliff:g id="SERVICE">%1$s</xliff:g> di avere il controllo totale del tuo dispositivo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se attivi <xliff:g id="SERVICE">%1$s</xliff:g>, il dispositivo non utilizzerà il blocco schermo per migliorare la crittografia dei dati."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Il pieno controllo è appropriato per le app che rispondono alle tue esigenze di accessibilità, ma non per gran parte delle app."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Aggiornato dall\'amministratore"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminato dall\'amministratore"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Per estendere la durata della batteria, il risparmio energetico:\n·Attiva il Tema scuro\n·Disattiva o limita le attività in background, alcuni effetti visivi e altre funzionalità come \"Ok Google\"\n\n"<annotation id="url">"Ulteriori informazioni"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Per estendere la durata della batteria, Risparmio energetico:\n·Attiva il Tema scuro\n·Disattiva o limita le attività in background, alcuni effetti visivi e altre funzionalità come \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Per contribuire a ridurre l\'utilizzo dei dati, la funzione Risparmio dati impedisce ad alcune app di inviare o ricevere dati in background. Un\'app in uso può accedere ai dati, ma potrebbe farlo con meno frequenza. Esempio: le immagini non vengono visualizzate finché non le tocchi."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Attivare Risparmio dati?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Attiva"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifiche"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Impostazioni rapide"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Finestra di dialogo Alimentazione"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Attiva/disattiva schermo diviso"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Schermata di blocco"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu Accessibilità"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra del titolo di <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> è stato inserito nel bucket RESTRICTED"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversazione"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversazione di gruppo"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 87b670a82e96..a6d538aefa96 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -204,9 +204,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"תתבצע מחיקה של המכשיר"</string> <string name="factory_reset_message" msgid="2657049595153992213">"לא ניתן להשתמש באפליקציה של מנהל המערכת.\n\nאם יש לך שאלות, יש ליצור קשר עם מנהל המערכת של הארגון."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"ההדפסה הושבתה על ידי <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ביטול חסימה של אפל\' אישיות"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"האפליקציות ייחסמו מחר"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"מנהל ה-IT לא מתיר השהיה של יותר מ-<xliff:g id="DAYS">%1$d</xliff:g> ימים של פרופיל העבודה"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"הפעלה של פרופיל העבודה"</string> <string name="me" msgid="6207584824693813140">"אני"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"אפשרויות טאבלט"</string> @@ -1675,6 +1678,10 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ניתן ללחוץ על שני מקשי עוצמת הקול למשך מספר שניות כדי להפעיל את <xliff:g id="SERVICE">%1$s</xliff:g>, תכונת נגישות. בעקבות זאת, ייתכן שאופן הפעולה של המכשיר ישתנה.\n\nאפשר לשנות את מקשי הקיצור האלה לתכונה נוספת ב\'הגדרות\' > \'נגישות\'."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"אני רוצה להפעיל"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"לא להפעיל"</string> + <!-- no translation found for accessibility_shortcut_menu_item_status_on (6608392117189732543) --> + <skip /> + <!-- no translation found for accessibility_shortcut_menu_item_status_off (5531598275559472393) --> + <skip /> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ברצונך להעניק לשירות <xliff:g id="SERVICE">%1$s</xliff:g> שליטה מלאה במכשיר?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"אם השירות <xliff:g id="SERVICE">%1$s</xliff:g> יופעל, המכשיר לא ישתמש בנעילת המסך כדי לשפר את הצפנת הנתונים."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"שליטה מלאה מתאימה לאפליקציות שעוזרות עם צורכי הנגישות שלך, אבל לא לרוב האפליקציות."</string> @@ -1838,8 +1845,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"עודכנה על ידי מנהל המערכת"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"נמחקה על ידי מנהל המערכת"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"אישור"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"התכונה \'חיסכון בסוללה\':\n·מפעילה עיצוב כהה\n·מכבה או מגבילה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות אחרות כמו \"Ok Google\", כדי להאריך את חיי הסוללה\n\n"<annotation id="url">"מידע נוסף"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"התכונה \'חיסכון בסוללה\':\n·מפעילה עיצוב כהה\n·מכבה או מגבילה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות אחרות כמו \"Ok Google\", כדי להאריך את חיי הסוללה"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"כדי לסייע בהפחתת השימוש בנתונים, חוסך הנתונים (Data Saver) מונע מאפליקציות מסוימות שליחה או קבלה של נתונים ברקע. אפליקציה שבה נעשה שימוש כרגע יכולה לגשת לנתונים, אבל בתדירות נמוכה יותר. המשמעות היא, למשל, שתמונות יוצגו רק לאחר שמקישים עליהן."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"להפעיל את חוסך הנתונים?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"הפעל"</string> @@ -2106,13 +2115,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"התראות"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"הגדרות מהירות"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"תיבת דו-שיח לגבי הסוללה"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"החלפת מצב של מסך מפוצל"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"מסך הנעילה"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"צילום מסך"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"תפריט נגישות"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"סרגל כיתוב של <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> התווספה לקטגוריה \'מוגבל\'"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"שיחה"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"שיחה קבוצתית"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 17924e47a920..4695d24dcd72 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"デバイスのデータが消去されます"</string> <string name="factory_reset_message" msgid="2657049595153992213">"管理アプリを使用できません。デバイスのデータはこれから消去されます。\n\nご不明な点がある場合は、組織の管理者にお問い合わせください。"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」により印刷は無効にされています。"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"個人用アプリのブロック解除"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"アプリは明日ブロックされます"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT 管理者は、仕事用プロファイルの一時停止が <xliff:g id="DAYS">%1$d</xliff:g> 日を超えることを許可していません"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"仕事用プロファイルを ON にする"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"個人用アプリは、仕事用プロファイルを ON にしない限りブロックされます"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"個人用アプリは、明日ブロックされます"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"仕事用プロファイルを有効にする"</string> <string name="me" msgid="6207584824693813140">"自分"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"タブレットオプション"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"音量大と音量小の両方のボタンを数秒ほど長押しすると、ユーザー補助機能の <xliff:g id="SERVICE">%1$s</xliff:g> が ON になります。この機能が ON になると、デバイスの動作が変わることがあります。\n\nこのショートカットは [設定] > [ユーザー補助] で別の機能に変更できます。"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ON にする"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ON にしない"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"オン"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"オフ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> にデバイスのフル コントロールを許可しますか?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> をオンにすると、デバイスデータの暗号化の強化に画面ロックは使用されなくなります。"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"フル コントロールは、ユーザー補助機能を必要とするユーザーをサポートするアプリには適していますが、ほとんどのアプリには適していません。"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"管理者により更新されています"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"管理者により削除されています"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"電池を長持ちさせるためにバッテリー セーバーが行う操作:\n·ダークテーマを ON にする\n·バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能を OFF にする、または制限する\n\n"<annotation id="url">"詳細"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"電池を長持ちさせるためにバッテリー セーバーが行う操作:\n·ダークテーマを ON にする\n·バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能を OFF にする、または制限する"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"データセーバーは、一部のアプリによるバックグラウンドでのデータ送受信を停止することでデータ使用量を抑制します。使用中のアプリからデータを送受信することはできますが、その頻度は低くなる場合があります。この影響として、たとえば画像はタップしないと表示されないようになります。"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"データセーバーを ON にしますか?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ON にする"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"通知"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"クイック設定"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"電源ダイアログ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"分割画面の切り替え"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ロック画面"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"スクリーンショット"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ユーザー補助機能メニュー"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> のキャプション バーです。"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> は RESTRICTED バケットに移動しました。"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"会話"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"グループの会話"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 5dac9b64da10..ee4d1169f1f3 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"თქვენი მოწყობილობა წაიშლება"</string> <string name="factory_reset_message" msgid="2657049595153992213">"ადმინისტრატორის აპის გამოყენება ვერ მოხერხდება. თქვენი მოწყობილობა ახლა ამოიშლება.\n\nთუ შეკითხვები გაქვთ, დაუკავშირდით თქვენი ორგანიზაციის ადმინისტრატორს."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"ბეჭდვა გათიშულია <xliff:g id="OWNER_APP">%s</xliff:g>-ის მიერ."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"განბლოკეთ თქვენი პირადი აპები"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"აპები ხვალ დაიბლოკება"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"თქვენი IT ადმინისტრატორი არ აძლევს უფლებას თქვენს სამსახურის პროფილს, დაპაუზებული იყოს <xliff:g id="DAYS">%1$d</xliff:g> დღეზე ხანგრძლივად."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"ჩართეთ სამსახურის პროფილი"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"თქვენი პირადი აპები დაბლოკილი იქნება, სანამ სამსახურის პროფილს არ ჩართავთ"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"თქვენი პირადი აპები ხვალ დაიბლოკება"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"სამსახურის პროფილის ჩართვა"</string> <string name="me" msgid="6207584824693813140">"მე"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ტაბლეტის პარამეტრები"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ხმის ორივე ღილაკზე რამდენიმე წამის განმავლობაში დაჭერით ჩაირთვება <xliff:g id="SERVICE">%1$s</xliff:g>, რომელიც მარტივი წვდომის ფუნქციაა. ამან შეიძლება შეცვალოს თქვენი მოწყობილობის მუშაობის პრინციპი.\n\nამ მალსახმობის შეცვლა სხვა ფუნქციით შეგიძლიათ აქ: პარამეტრები > აპები."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ჩართვა"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"არ ჩაირთოს"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ჩართულია"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"გამორთულია"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"დართავთ ნებას <xliff:g id="SERVICE">%1$s</xliff:g>-ს, სრულად მართოს თქვენი მოწყობილობა?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g>-ს თუ ჩართავთ, მონაცემთა დაშიფვრის გასაძლიერებლად თქვენი მოწყობილობა ეკრანის დაბლოკვას არ გამოიყენებს."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"სრული კონტროლი გამოსადეგია აპებისთვის, რომლებიც მარტივი წვდომის საჭიროებისას გეხმარებათ, მაგრამ არა აპების უმრავლესობისთვის."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"განახლებულია თქვენი ადმინისტრატორის მიერ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"წაიშალა თქვენი ადმინისტრატორის მიერ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"კარგი"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ბატარეის მუშაობის განრძლივობის მიზნით, ბატარეის დამზოგველი:\n·ირთვება ბნელ თემაზე\n·თიშავს ან ზღუდავს ფონის აქტივობებს, გარკვეულ ვიზუალურ ეფექტებს და სახვა შესაძლებლობებს, როგორიც არის “Hey Google”\n\n"<annotation id="url">"შეიტყვეთ მეტი"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ბატარეის მუშაობის გახანგრძლივების მიზნით, ბატარეის დამზოგველი:\n·ირთვება ბნელ თემაზე\n·თიშავს ან ზღუდავს ფონის აქტივობებს, გარკვეულ ვიზუალურ ეფექტებს და სახვა შესაძლებლობებს, როგორიც არის “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"მობილური ინტერნეტის მოხმარების შემცირების მიზნით, მონაცემთა დამზოგველი ზოგიერთ აპს ფონურ რეჟიმში მონაცემთა გაგზავნასა და მიღებას შეუზღუდავს. თქვენ მიერ ამჟამად გამოყენებული აპი მაინც შეძლებს მობილურ ინტერნეტზე წვდომას, თუმცა ამას ნაკლები სიხშირით განახორციელებს. ეს ნიშნავს, რომ, მაგალითად, სურათები არ გამოჩნდება მანამ, სანამ მათ საგანგებოდ არ შეეხებით."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ჩაირთოს მონაცემთა დამზოგველი?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ჩართვა"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"შეტყობინებები"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"სწრაფი პარამეტრები"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ელკვების დიალოგი"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"გაყოფილი ეკრანის გადართვა"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ჩაკეტილი ეკრანი"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ეკრანის ანაბეჭდი"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"მარტივი წვდომის მენიუ"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის სუბტიტრების ზოლი."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> მოთავსდა კალათაში „შეზღუდული“"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"მიმოწერა"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ჯგუფური მიმოწერა"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index d2773a2f69a1..29cce56a7f90 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Құрылғыңыздағы деректер өшіріледі"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Әкімші қолданбасын пайдалану мүмкін емес. Қазір құрылғыдағы деректер өшіріледі\n\nСұрақтарыңыз болса, ұйым әкімшісіне хабарласыңыз."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Басып шығаруды <xliff:g id="OWNER_APP">%s</xliff:g> өшірді."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Жеке қолданбалардың құлпын ашу"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Қолданбалар ертең құлыпталады"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Әкімші жұмыс профилін <xliff:g id="DAYS">%1$d</xliff:g> күннен аса мерзімге өшіруге рұқсат етпейді."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Жұмыс профиліңізді қосыңыз"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Жұмыс профиліңізді қоспайынша, жеке қолданбалар бөгеледі."</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Жеке қолданбаларыңыз ертең бөгеледі."</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Жұмыс профилін қосу"</string> <string name="me" msgid="6207584824693813140">"Мен"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Планшет опциялары"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Дыбыс деңгейі пернелерін бірнеше секунд басып тұрсаңыз, <xliff:g id="SERVICE">%1$s</xliff:g> арнайы қызметі іске қосылады. Бұл – құрылғының жүмысына әсер етуі мүмкін.\n\nБұл таңбашаны басқа функцияға \"Параметрлер > Арнайы мүмкіндіктер\" бөлімінен өзгерте аласыз."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Қосылсын"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Қосылмасын"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ҚОСУЛЫ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ӨШІРУЛІ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> қызметі құрылғыңызды толық басқаруына рұқсат етілсін бе?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> қоссаңыз, құрылғыңыз деректерді шифрлау үшін экранды бекітуді пайдаланбайды."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Арнайы мүмкіндіктер бойынша көмектесетін қолданбаларға ғана құрылғыны толық басқару рұқсатын берген дұрыс."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Әкімші жаңартқан"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Әкімші жойған"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Жарайды"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Батарея жұмысының ұзақтығын арттыру үшін Battery Saver:\n·Қараңғы тақырыпты іске қосады\n·фондық әрекеттерді, кейбір көрнекі әсерлерді және \"Ok Google\" сияқты басқа да функцияларды өшіреді немесе шектейді.\n\n"<annotation id="url">"Толығырақ"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Батарея жұмысының ұзақтығын арттыру үшін Battery Saver:\n·Қараңғы тақырыпты іске қосады;\n·фондық әрекеттерді, кейбір көрнекі әсерлерді және \"Ok Google\" сияқты басқа да функцияларды өшіреді немесе шектейді."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Дерек шығынын азайту үшін Data Saver функциясы кейбір қолданбаларға деректерді фондық режимде жіберуге және алуға жол бермейді. Ашық тұрған қолданба деректерді пайдаланады, бірақ шектеулі шамада (мысалы, кескіндер оларды түрткенге дейін көрсетілмейді)."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Data Saver функциясын қосу керек пе?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Қосу"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Хабарландырулар"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Жылдам параметрлер"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Қуат диалогтік терезесі"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Экранды бөлу мүмкіндігін қосу/өшіру"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Құлып экраны"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Арнайы мүмкіндіктер мәзірі"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасының жазу жолағы."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ШЕКТЕЛГЕН себетке салынды."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Чат"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Топтық чат"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 48af34027ed1..7f482bc4b452 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"ឧបករណ៍របស់អ្នកនឹងត្រូវបានលុប"</string> <string name="factory_reset_message" msgid="2657049595153992213">"មិនអាចប្រើកម្មវិធីអ្នកគ្រប់គ្រងបានទេ។ ឧបករណ៍របស់អ្នកនឹងលុបឥឡូវនេះ។\n\nប្រសិនបើអ្នកមានសំណួរផ្សេងៗ សូមទាក់ទងទៅអ្នកគ្រប់គ្រងស្ថាប័នរបស់អ្នក។"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"ការបោះពុម្ពត្រូវបានបិទដោយ <xliff:g id="OWNER_APP">%s</xliff:g> ។"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ឈប់ទប់ស្កាត់កម្មវិធីផ្ទាល់ខ្លួនរបស់អ្នក"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"កម្មវិធីនឹងត្រូវទប់ស្កាត់ថ្ងៃស្អែក"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"អ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យារបស់អ្នកមិនអនុញ្ញាតឱ្យផ្អាកកម្រងព័ត៌មានការងាររបស់អ្នកលើសពី <xliff:g id="DAYS">%1$d</xliff:g> ថ្ងៃទេ"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"បើកកម្រងព័ត៌មានការងាររបស់អ្នក"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"កម្មវិធីផ្ទាល់ខ្លួនរបស់អ្នកត្រូវបានទប់ស្កាត់ រហូតទាល់តែអ្នកបើកកម្រងព័ត៌មានការងាររបស់អ្នក"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"កម្មវិធីផ្ទាល់ខ្លួនរបស់អ្នកនឹងត្រូវបានទប់ស្កាត់នៅថ្ងៃស្អែក"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"បើកកម្រងព័ត៌មានការងារ"</string> <string name="me" msgid="6207584824693813140">"ខ្ញុំ"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ជម្រើសកុំព្យូទ័របន្ទះ"</string> @@ -1633,6 +1633,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ការសង្កត់គ្រាប់ចុចកម្រិតសំឡេងទាំងពីរឱ្យជាប់រយៈពេលពីរបីវិនាទីនឹងបើក <xliff:g id="SERVICE">%1$s</xliff:g> ដែលជាមុខងារភាពងាយប្រើ។ ការធ្វើបែបនេះអាចផ្លាស់ប្ដូររបៀបដែលឧបករណ៍របស់អ្នកដំណើរការ។\n\nអ្នកអាចប្ដូរផ្លូវកាត់នេះទៅមុខងារផ្សេងទៀតនៅក្នុងការកំណត់ > ភាពងាយស្រួល។"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"បើក"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"កុំបើក"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"បើក"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"បិទ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"អនុញ្ញាតឱ្យ <xliff:g id="SERVICE">%1$s</xliff:g> មានសិទ្ធិគ្រប់គ្រងឧបករណ៍របស់អ្នកទាំងស្រុងឬ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"បើអ្នកបើក <xliff:g id="SERVICE">%1$s</xliff:g> ឧបករណ៍របស់អ្នកនឹងមិនប្រើការចាក់សោអេក្រង់របស់អ្នក ដើម្បីបង្កើនប្រសិទ្ធភាពការអ៊ីនគ្រីបទិន្នន័យទេ។"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ការគ្រប់គ្រងទាំងស្រុងមានលក្ខណៈសមស្របសម្រាប់កម្មវិធី ដែលជួយអ្នកទាក់ទងនឹងការប្រើមុខងារភាពងាយស្រួល ប៉ុន្តែមិនសមស្របសម្រាប់កម្មវិធីភាគច្រើនទេ។"</string> @@ -1794,8 +1796,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"ធ្វើបច្ចុប្បន្នភាពដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"លុបដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"យល់ព្រម"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ដើម្បីបង្កើនកម្រិតថាមពលថ្ម កម្មវិធីសន្សំថ្ម៖\n·បើករចនាប័ទ្មងងឹត\n·បិទ ឬដាក់កំហិតលើសកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពលជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀតដូចជា “Hey Google” ជាដើម\n\n"<annotation id="url">"ស្វែងយល់បន្ថែម"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ដើម្បីបង្កើនកម្រិតថាមពលថ្ម កម្មវិធីសន្សំថ្ម៖\n·បើករចនាប័ទ្មងងឹត\n·បិទ ឬដាក់កំហិតលើសកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពលជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀតដូចជា “Hey Google” ជាដើម"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ដើម្បីជួយកាត់បន្ថយការប្រើប្រាស់ទិន្នន័យ កម្មវិធីសន្សំសំចៃទិន្នន័យរារាំងកម្មវិធីមួយចំនួនមិនឲ្យបញ្ជូន ឬទទួលទិន្នន័យនៅផ្ទៃខាងក្រោយទេ។ កម្មវិធីដែលអ្នកកំពុងប្រើនាពេលបច្ចុប្បន្នអាចចូលប្រើប្រាស់ទិន្នន័យបាន ប៉ុន្តែអាចនឹងមិនញឹកញាប់ដូចមុនទេ។ ឧទាហរណ៍ រូបភាពមិនបង្ហាញទេ លុះត្រាតែអ្នកប៉ះរូបភាពទាំងនោះ។"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"បើកកម្មវិធីសន្សំសំចៃទិន្នន័យ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"បើក"</string> @@ -2040,13 +2044,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ការជូនដំណឹង"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ការកំណត់រហ័ស"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ប្រអប់ថាមពល"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"បិទ/បើកមុខងារបំបែកអេក្រង់"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"អេក្រង់ចាក់សោ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"រូបថតអេក្រង់"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ម៉ឺនុយភាពងាយស្រួល"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"របារពណ៌នាអំពី <xliff:g id="APP_NAME">%1$s</xliff:g>។"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ត្រូវបានដាក់ទៅក្នុងធុងដែលបានដាក់កំហិត"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>៖"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"ការសន្ទនា"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ការសន្ទនាជាក្រុម"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 64002ef0d15f..c03f37e57464 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string> <string name="factory_reset_message" msgid="2657049595153992213">"ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ಸಾಧನವನ್ನು ಇದೀಗ ಅಳಿಸಲಾಗುತ್ತದೆ.\n\nನಿಮ್ಮಲ್ಲಿ ಪ್ರಶ್ನೆಗಳಿದ್ದರೆ, ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ಮೂಲಕ ಪ್ರಿಂಟಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್ಗಳ ನಿರ್ಬಂಧ ತೆಗೆಯಿರಿ"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ಆ್ಯಪ್ಗಳನ್ನು ನಾಳೆ ನಿರ್ಬಂಧಿಸಲಾಗುವುದು"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಅನ್ನು <xliff:g id="DAYS">%1$d</xliff:g> ದಿನಗಳಿಗಿಂತ ಹೆಚ್ಚು ಸಮಯ ವಿರಾಮಗೊಳಿಸಲು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುವವರೆಗೆ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಆ್ಯಪ್ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತದೆ"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಆ್ಯಪ್ಗಳನ್ನು ನಾಳೆ ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತದೆ"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string> <string name="me" msgid="6207584824693813140">"ನಾನು"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ಟ್ಯಾಬ್ಲೆಟ್ ಆಯ್ಕೆಗಳು"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಕೆಲವು ಸೆಕೆಂಡುಗಳ ಕಾಲ ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳುವುದರಿಂದ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯವಾದ <xliff:g id="SERVICE">%1$s</xliff:g> ಆನ್ ಆಗುತ್ತದೆ. ಇದು ನಿಮ್ಮ ಸಾಧನವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಬಹುದು.\n\nನೀವು ಈ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಸೆಟ್ಟಿಂಗ್ಗಳು ಮತ್ತು ಅಕ್ಸೆಸಿಬಿಲಿಟಿಯಲ್ಲಿನ ಮತ್ತೊಂದು ವೈಶಿಷ್ಟ್ಯಕ್ಕೆ ಬದಲಾಯಿಸಬಹುದು."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ಆನ್ ಮಾಡಿ"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ಆನ್ ಮಾಡಬೇಡಿ"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ಆನ್ ಆಗಿದೆ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ಆಫ್ ಆಗಿದೆ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ನಿಮ್ಮ ಸಾಧನದ ಪೂರ್ಣ ನಿಯಂತ್ರಣ ಹೊಂದಲು <xliff:g id="SERVICE">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"ನೀವು <xliff:g id="SERVICE">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಿದರೆ, ನಿಮ್ಮ ಸಾಧನವು ಡೇಟಾ ಎನ್ಕ್ರಿಪ್ಶನ್ ಅನ್ನು ವರ್ಧಿಸಲು ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ಲಾಕ್ ಅನ್ನು ಬಳಸುವುದಿಲ್ಲ."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ಪ್ರವೇಶಿಸುವಿಕೆಯ ಅವಶ್ಯಕತೆಗಳಿಗೆ ಸಹಾಯ ಮಾಡುವ ಆ್ಯಪ್ಗಳಿಗೆ ಪೂರ್ಣ ನಿಯಂತ್ರಣ ನೀಡುವುದು ಸೂಕ್ತವಾಗಿರುತ್ತದೆ, ಆದರೆ ಬಹುತೇಕ ಆ್ಯಪ್ಗಳಿಗೆ ಇದು ಸೂಕ್ತವಲ್ಲ."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡಲ್ಪಟ್ಟಿದೆ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಳಿಸಿದ್ದಾರೆ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ಸರಿ"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ವಿಸ್ತರಿಸಲು, ಬ್ಯಾಟರಿ ಸೇವರ್:\n·ಡಾರ್ಕ್ ಥೀಮ್ ಅನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ\n·ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ, ಕೆಲವು ದೃಶ್ಯಾತ್ಮಕ ಎಫೆಕ್ಟ್ಗಳು ಮತ್ತು “ಹೇ Google” ನಂತಹ ಇತರ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಆಫ್ ಮಾಡುತ್ತದೆ ಅಥವಾ ನಿರ್ಬಂಧಿಸುತ್ತದೆ\n\n"<annotation id="url">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ವಿಸ್ತರಿಸಲು, ಬ್ಯಾಟರಿ ಸೇವರ್:\n·ಡಾರ್ಕ್ ಥೀಮ್ ಅನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ\n·ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ, ಕೆಲವು ವಿಷುವಲ್ ಎಫೆಕ್ಟ್ಗಳು ಮತ್ತು “ಹೇ Google” ನಂತಹ ಇತರ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಆಫ್ ಮಾಡುತ್ತದೆ ಅಥವಾ ನಿರ್ಬಂಧಿಸುತ್ತದೆ"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ಡೇಟಾ ಬಳಕೆ ಕಡಿಮೆ ಮಾಡುವ ನಿಟ್ಟಿನಲ್ಲಿ, ಡೇಟಾ ಸೇವರ್ ಕೆಲವು ಅಪ್ಲಿಕೇಶನ್ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಡೇಟಾ ಕಳುಹಿಸುವುದನ್ನು ಅಥವಾ ಸ್ವೀಕರಿಸುವುದನ್ನು ತಡೆಯುತ್ತದೆ. ನೀವು ಪ್ರಸ್ತುತ ಬಳಸುತ್ತಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು ಆದರೆ ಪದೇ ಪದೇ ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಇದರರ್ಥ, ಉದಾಹರಣೆಗೆ, ನೀವು ಅವುಗಳನ್ನು ಟ್ಯಾಪ್ ಮಾಡುವವರೆಗೆ ಆ ಚಿತ್ರಗಳು ಕಾಣಿಸಿಕೊಳ್ಳುವುದಿಲ್ಲ."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ಡೇಟಾ ಸೇವರ್ ಆನ್ ಮಾಡಬೇಕೇ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ಆನ್ ಮಾಡಿ"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ಅಧಿಸೂಚನೆಗಳು"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ಪವರ್ ಡೈಲಾಗ್"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ಸ್ಪ್ಲಿಟ್-ಸ್ಕ್ರೀನ್ ಟಾಗಲ್ ಮಾಡಿ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ಪ್ರವೇಶಿಸುವಿಕೆ ಮೆನು"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್ನ ಶೀರ್ಷಿಕೆಯ ಪಟ್ಟಿ."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ಬಂಧಿತ ಬಕೆಟ್ಗೆ ಹಾಕಲಾಗಿದೆ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"ಸಂವಾದ"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ಗುಂಪು ಸಂವಾದ"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index ac691ae1189c..66df0559def5 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"기기가 삭제됩니다."</string> <string name="factory_reset_message" msgid="2657049595153992213">"관리자 앱을 사용할 수 없습니다. 곧 기기가 삭제됩니다.\n\n궁금한 점이 있으면 조직의 관리자에게 문의하세요."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g>에 의해 사용 중지되었습니다."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"개인 앱 차단 해제"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"내일부터 앱이 차단됨"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT 관리자가 <xliff:g id="DAYS">%1$d</xliff:g>일보다 오래 직장 프로필을 일시중지하도록 허용하지 않습니다."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"직장 프로필 사용 설정"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"직장 프로필을 사용 설정할 때까지 개인 앱이 차단됩니다."</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"개인 앱이 내일 차단됩니다."</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"직장 프로필 사용 설정"</string> <string name="me" msgid="6207584824693813140">"나"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"태블릿 옵션"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"볼륨 키 2개를 몇 초 동안 길게 누르면 <xliff:g id="SERVICE">%1$s</xliff:g> 접근성 기능이 사용 설정됩니다. 이렇게 되면 기기 작동 방식이 달라질 수 있습니다.\n\n설정 > 접근성에서 이 단축키를 다른 기능으로 변경할 수 있습니다."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"사용 설정"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"사용 안 함"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"사용"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"사용 안함"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>에서 기기를 완전히 제어하도록 허용하시겠습니까?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g>을(를) 사용 설정하면 기기에서 데이터 암호화를 개선하기 위해 화면 잠금을 사용하지 않습니다."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"접근성 관련 지원을 제공하는 앱에는 완벽한 제어권을 부여하는 것이 좋으나, 대부분의 앱에는 적합하지 않습니다."</string> @@ -1792,8 +1794,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"관리자에 의해 업데이트되었습니다."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"관리자에 의해 삭제되었습니다."</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"확인"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"배터리 수명을 늘리기 위해 절전 모드가 다음과 같이 작동합니다.\n·어두운 테마를 사용 설정합니다.\n·백그라운드 활동, 일부 시각 효과 및 \'Hey Google\'과 같은 기타 기능을 사용 중지하거나 제한합니다.\n\n"<annotation id="url">"자세히 알아보기"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"배터리 수명을 늘리기 위해 절전 모드가 다음과 같이 작동합니다.\n·어두운 테마를 사용 설정합니다.\n·백그라운드 활동, 일부 시각 효과 및 \'Hey Google\'과 같은 기타 기능을 사용 중지하거나 제한합니다."</string> + <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"배터리 수명을 늘리기 위해 절전 모드가 다음과 같이 작동합니다.\n\n•어두운 테마를 사용 설정합니다.\n•백그라운드 활동, 일부 시각 효과 및 \'Hey Google\'과 같은 기타 기능을 사용 중지하거나 제한합니다.\n\n"<annotation id="url">"자세히 알아보기"</annotation></string> + <string name="battery_saver_description" msgid="8587408568232177204">"배터리 수명을 늘리기 위해 절전 모드가 다음과 같이 작동합니다.\n\n•어두운 테마를 사용 설정합니다.\n•백그라운드 활동, 일부 시각 효과 및 \'Hey Google\'과 같은 기타 기능을 사용 중지하거나 제한합니다."</string> <string name="data_saver_description" msgid="4995164271550590517">"데이터 사용량을 줄이기 위해 데이터 절약 모드는 일부 앱이 백그라운드에서 데이터를 전송하거나 수신하지 못하도록 합니다. 현재 사용 중인 앱에서 데이터에 액세스할 수 있지만 빈도가 줄어듭니다. 예를 들면, 이미지를 탭하기 전에는 이미지가 표시되지 않습니다."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"데이터 절약 모드를 사용 설정하시겠습니까?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"사용 설정"</string> @@ -2038,13 +2040,14 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"알림"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"빠른 설정"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"전원 대화상자"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"화면 분할 모드 전환"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"잠금 화면"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"스크린샷"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"접근성 메뉴"</string> + <string name="accessibility_system_action_accessibility_button_label" msgid="5941347017132886642">"터치식 접근성 단축키"</string> + <string name="accessibility_system_action_accessibility_button_chooser_label" msgid="6973618519666227981">"터치식 접근성 단축키 선택 도구"</string> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>의 자막 표시줄입니다."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 항목이 RESTRICTED 버킷으로 이동함"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"이미지 보냄"</string> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"대화"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"그룹 대화"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 31c723ff8b67..e76ca6304e57 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Түзмөгүңүз тазаланат"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Түзмөктү башкаруучу колдонмо жараксыз. Түзмөгүңүз азыр тазаланат.\n\nСуроолоруңуз болсо, ишканаңыздын администраторуна кайрылыңыз."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Басып чыгаруу <xliff:g id="OWNER_APP">%s</xliff:g> тарабынан өчүрүлдү."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Жеке колд. бөгөттөн чыгарыңыз"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Колдонмолор эртең бөгөттөлөт"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT администраторуңуз жумуш профилиңиздин <xliff:g id="DAYS">%1$d</xliff:g> күндөн ашык тындырылышына тыюу салды"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Жумуш профилиңизди күйгүзүңүз"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Жумуш профилиңизди күйгүзмөйүнчө жеке колдонмолоруңуз бөгөттөлгөн боюнча калат"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Жеке колдонмолоруңуз эртең бөгөттөлөт"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Жумуш профилин күйгүзүү"</string> <string name="me" msgid="6207584824693813140">"Мен"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Планшет мүмкүнчүлүктөрү"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып турса, <xliff:g id="SERVICE">%1$s</xliff:g>, атайын мүмкүнчүлүктөр күйгүзүлөт. Бул түзмөгүңүздүн ишин өзгөртүшү мүмкүн.\n\nБул ыкчам баскычты Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнөн башка функцияга өзгөртө аласыз."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Күйгүзүлсүн"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Күйгүзүлбөсүн"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"КҮЙҮК"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ӨЧҮК"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматына түзмөгүңүздү толугу менен көзөмөлдөөгө уруксат бересизби?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Эгер <xliff:g id="SERVICE">%1$s</xliff:g> күйгүзүлсө, түзмөгүңүз дайын-даректерди шифрлөөнү күчтөндүрүү үчүн экраныңыздын кулпусун пайдаланбайт."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Толук көзөмөл атайын мүмкүнчүлүктөрдү пайдаланууга керек, бирок калган көпчүлүк колдонмолорго кереги жок."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Администраторуңуз жаңыртып койгон"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Администраторуңуз жок кылып салган"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ЖАРАЙТ"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Батареяны үнөмдөө үчүн Батареяны үнөмдөгүч:\n·Караңгы теманы күйгүзөт\n·Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Батареянын иштешин узартуу үчүн, Батареяны үнөмдөөчү режим:\n·Караңгы теманы күйгүзөт;\n·Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Трафикти үнөмдөө режиминде айрым колдонмолор дайын-даректерди фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо дайын-даректерди жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Трафикти үнөмдөө режимин иштетесизби?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Күйгүзүү"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Билдирмелер"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Ыкчам жөндөөлөр"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Кубат диалогу"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Экранды бөлүүнү күйгүзүү же өчүрүү"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Кулпуланган экран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Атайын мүмкүнчүлүктөр менюсу"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунун маалымат тилкеси."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ЧЕКТЕЛГЕН чакага коюлган"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Жазышуу"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Топтук маек"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 5ff7a692621a..fbcae03c92e6 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"ອຸປະກອນຂອງທ່ານຈະຖືກລຶບ"</string> <string name="factory_reset_message" msgid="2657049595153992213">"ບໍ່ສາມາດໃຊ້ແອັບຜູ້ເບິ່ງແຍງລະບົບໄດ້. ອຸປະກອນຂອງທ່ານຈະຖືກລຶບຂໍ້ມູນໃນຕອນນີ້.\n\nຫາກທ່ານມີຄຳຖາມ, ໃຫ້ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບອົງກອນຂອງທ່ານ."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"ການພິມຖືກປິດໄວ້ໂດຍ <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ປົດບລັອກແອັບສ່ວນຕົວຂອງທ່ານ"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ແອັບຈະຖືກບລັອກໃນມື້ອື່ນ"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ຢຸດໂປຣໄຟລ໌ວຽກຂອງທ່ານເກີນ <xliff:g id="DAYS">%1$d</xliff:g> ມື້ໄດ້"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"ເປີດໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"ແອັບສ່ວນຕົວຂອງທ່ານຈະຖືກບລັອກໄວ້ຈົນກວ່າທ່ານຈະເປີດໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານ"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"ແອັບສ່ວນຕົວຂອງທ່ານຈະຖືກບລັອກໄວ້ໃນມື້ອື່ນ"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"ເປີດໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string> <string name="me" msgid="6207584824693813140">"ຂ້າພະເຈົ້າ"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ໂຕເລືອກແທັບເລັດ"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ສອງສາມວິນາທີເພື່ອເປີດໃຊ້ <xliff:g id="SERVICE">%1$s</xliff:g>, ຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງ. ນີ້ອາດປ່ຽນວິທີການເຮັດວຽກຂອງອຸປະກອນທ່ານ.\n\nທ່ານສາມາດປ່ຽນທາງລັດນີ້ເປັນຄຸນສົມບັດອື່ນໄດ້ໃນການຕັ້ງຄ່າ > ການຊ່ວຍເຂົ້າເຖິງ."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ເປີດໃຊ້"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ບໍ່ເປີດ"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ເປີດ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ປິດ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ອະນຸຍາດໃຫ້ <xliff:g id="SERVICE">%1$s</xliff:g> ຄວບຄຸມອຸປະກອນທ່ານໄດ້ເຕັມຮູບແບບບໍ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"ຫາກທ່ານເປີດໃຊ້ <xliff:g id="SERVICE">%1$s</xliff:g>, ອຸປະກອນຂອງທ່ານຈະບໍ່ໃຊ້ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອເພີ່ມການເຂົ້າລະຫັດຂໍ້ມູນ."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ການຄວບຄຸມແບບເຕັມຮູບແບບແມ່ນເໝາະສົມສຳລັບແອັບທີ່ຊ່ວຍທ່ານໃນດ້ານການຊ່ວຍເຂົ້າເຖິງ, ແຕ່ບໍ່ເໝາະສຳລັບທຸກແອັບ."</string> @@ -1792,8 +1794,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"ຖືກອັບໂຫລດໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ຖືກລຶບອອກໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ຕົກລົງ"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ເພື່ອຍືດອາຍຸແບັດເຕີຣີ, ຕົວປະຢັດແບັດເຕີຣີຈະ:\n·ເປີດໃຊ້ຮູບແບບສີສັນມືດ\n·ປິດ ຫຼື ຈຳກັດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກດ້ານພາບບາງຢ່າງ ແລະ ຄຸນສົມບັດອື່ນໆ ເຊັ່ນ: “Hey Google”\n\n"<annotation id="url">"ສຶກສາເພີ່ມເຕີມ"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ເພື່ອຍືດອາຍຸແບັດເຕີຣີ, ຕົວປະຢັດແບັດເຕີຣີຈະ:\n·ເປີດໃຊ້ຮູບແບບສີສັນມືດ\n·ປິດ ຫຼື ຈຳກັດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກດ້ານພາບບາງຢ່າງ ແລະ ຄຸນສົມບັດອື່ນໆ ເຊັ່ນ: “Hey Google”"</string> + <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"ເພື່ອຍືດອາຍຸແບັດເຕີຣີ, ຕົວປະຢັດແບັດເຕີຣີຈະ:\n\n•ເປີດໃຊ້ຮູບແບບສີສັນມືດ\n•ປິດ ຫຼື ຈຳກັດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກດ້ານພາບບາງຢ່າງ ແລະ ຄຸນສົມບັດອື່ນໆ ເຊັ່ນ: “Hey Google”\n\n"<annotation id="url">"ສຶກສາເພີ່ມເຕີມ"</annotation></string> + <string name="battery_saver_description" msgid="8587408568232177204">"ເພື່ອຍືດອາຍຸແບັດເຕີຣີ, ຕົວປະຢັດແບັດເຕີຣີຈະ:\n\n•ເປີດໃຊ້ຮູບແບບສີສັນມືດ\n•ປິດ ຫຼື ຈຳກັດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກດ້ານພາບບາງຢ່າງ ແລະ ຄຸນສົມບັດອື່ນໆ ເຊັ່ນ: “Hey Google”"</string> <string name="data_saver_description" msgid="4995164271550590517">"ເພື່ອຊ່ວຍຫຼຸດຜ່ອນການນຳໃຊ້ຂໍ້ມູນ, ຕົວປະຢັດອິນເຕີເນັດຈະປ້ອງກັນບໍ່ໃຫ້ບາງແອັບສົ່ງ ຫຼື ຮັບຂໍ້ມູນໃນພື້ນຫຼັງ. ແອັບໃດໜຶ່ງທີ່ທ່ານກຳລັງໃຊ້ຢູ່ຈະສາມາດເຂົ້າເຖິງຂໍ້ມູນໄດ້ ແຕ່ອາດເຂົ້າເຖິງໄດ້ຖີ່ໜ້ອຍລົງ. ນີ້ອາດໝາຍຄວາມວ່າ ຮູບພາບຕ່າງໆອາດບໍ່ສະແດງຈົນກວ່າທ່ານຈະແຕະໃສ່ກ່ອນ."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ເປີດຕົວປະຢັດອິນເຕີເນັດບໍ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ເປີດໃຊ້"</string> @@ -2038,13 +2040,14 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ການແຈ້ງເຕືອນ"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ການຕັ້ງຄ່າດ່ວນ"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ກ່ອງໂຕ້ຕອບການເປີດປິດ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ເປີດ/ປິດການແບ່ງໜ້າຈໍ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ໜ້າຈໍລັອກ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ຮູບໜ້າຈໍ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ເມນູການຊ່ວຍເຂົ້າເຖິງ"</string> + <string name="accessibility_system_action_accessibility_button_label" msgid="5941347017132886642">"ທາງລັດການຊ່ວຍເຂົ້າເຖິງຢູ່ໜ້າຈໍ"</string> + <string name="accessibility_system_action_accessibility_button_chooser_label" msgid="6973618519666227981">"ຕົວເລືອກທາງລັດການຊ່ວຍເຂົ້າເຖິງຢູ່ໜ້າຈໍ"</string> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"ແຖບຄຳບັນຍາຍຂອງ <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ຖືກວາງໄວ້ໃນກະຕ່າ \"ຈຳກັດ\" ແລ້ວ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ສົ່ງຮູບແລ້ວ"</string> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"ການສົນທະນາ"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ການສົນທະນາກຸ່ມ"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 2b041565f416..56483e00999e 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -204,9 +204,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Įrenginys bus ištrintas"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Administratoriaus programos negalima naudoti. Dabar įrenginio duomenys bus ištrinti.\n\nJei turite klausimų, susisiekite su organizacijos administratoriumi."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Neleidžiama spausdinti (<xliff:g id="OWNER_APP">%s</xliff:g>)."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Asm. progr. blok. panaikinim."</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Progr. bus užblokuotos rytoj"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT administratorius neleidžia sustabdyti darbo profilio ilgiau nei <xliff:g id="DAYS">%1$d</xliff:g> d."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Įjunkite darbo profilį"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Asmeninės programos bus užblokuotos, kol įjungsite darbo profilį"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Jūsų asmeninės programos rytoj bus užblokuotos"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Įjungti darbo profilį"</string> <string name="me" msgid="6207584824693813140">"Aš"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Planšetinio kompiuterio parinktys"</string> @@ -1675,6 +1675,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Paspaudus abu garsumo klavišus ir palaikius kelias sekundes įjungiama pritaikymo neįgaliesiems funkcija „<xliff:g id="SERVICE">%1$s</xliff:g>“. Tai gali pakeisti įrenginio veikimą.\n\nGalite pakeisti šį spartųjį klavišą į kitą funkciją skiltyje „Nustatymai“ > „Pritaikomumas“."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Įjungti"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Neįjungti"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ĮJUNGTA"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IŠJUNGTA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Leisti „<xliff:g id="SERVICE">%1$s</xliff:g>“ valdyti visas įrenginio funkcijas?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jei įjungsite „<xliff:g id="SERVICE">%1$s</xliff:g>“, įrenginyje nebus naudojamas ekrano užraktas siekiant patobulinti duomenų šifruotę."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Galimybę valdyti visas funkcijas patariama suteikti programoms, kurios padeda specialiųjų poreikių turintiems asmenims, bet ne daugumai programų."</string> @@ -1838,8 +1840,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Atnaujino administratorius"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Ištrynė administratorius"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Gerai"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Kad akumuliatorius veiktų ilgiau, akumuliatoriaus tausojimo priemonė:\n·įjungia tamsiąją temą;\n·išjungia arba apriboja veiklą fone, kai kuriuos vaizdinius efektus ir kitas funkcijas, pvz., „Hey Google“.\n\n"<annotation id="url">"Sužinokite daugiau"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Kad akumuliatorius veiktų ilgiau, akumuliatoriaus tausojimo priemonė:\n·įjungia tamsiąją temą;\n·išjungia arba apriboja veiklą fone, kai kuriuos vaizdinius efektus ir kitas funkcijas, pvz., „Hey Google“."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Kad padėtų sumažinti duomenų naudojimą, Duomenų taupymo priemonė neleidžia kai kurioms programoms siųsti ar gauti duomenų fone. Šiuo metu naudojama programa gali pasiekti duomenis, bet tai bus daroma rečiau. Tai gali reikšti, kad, pvz., vaizdai nebus pateikiami, jei jų nepaliesite."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Įj. Duomenų taupymo priemonę?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Įjungti"</string> @@ -2106,13 +2110,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Pranešimai"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Spartieji nustatymai"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Maitinimo dialogo langas"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Perjungti išskaidyto ekrano režimą"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Užrakinimo ekranas"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekrano kopija"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Pritaikomumo meniu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ antraštės juosta."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"„<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>“ įkeltas į grupę APRIBOTA"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Pokalbis"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupės pokalbis"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index c80e3ac45e99..70056e828ff1 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -202,9 +202,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Jūsu ierīces dati tiks dzēsti"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Administratora lietotni nevar izmantot. Ierīcē saglabātie dati tiks dzēsti.\n\nJa jums ir kādi jautājumi, sazinieties ar savas organizācijas administratoru."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Drukāšanu atspējoja <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Atbloķējiet person. lietotnes"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Lietotnes tiks bloķētas rīt"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Jūsu IT administrators neatļauj apturēt jūsu darba profila darbību ilgāk nekā <xliff:g id="DAYS">%1$d</xliff:g> dienas"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Darba profila ieslēgšana"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Jūsu personīgās lietotnes būs bloķētas, līdz ieslēgsiet savu darba profilu."</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Jūsu personīgās lietotnes rīt tiks bloķētas."</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Ieslēgt darba profilu"</string> <string name="me" msgid="6207584824693813140">"Man"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Planšetdatora opcijas"</string> @@ -1653,6 +1653,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Turot nospiestus abus skaļuma taustiņus dažas sekundes, tiek ieslēgta pieejamības funkcija <xliff:g id="SERVICE">%1$s</xliff:g>. Tas var mainīt ierīces darbību.\n\nŠo saīsni uz citu funkciju varat mainīt šeit: Iestatījumi > Pieejamība."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ieslēgt"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Neieslēgt"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"IESLĒGTA"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IZSLĒGTA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vai atļaut pakalpojumam <xliff:g id="SERVICE">%1$s</xliff:g> pilnībā kontrolēt jūsu ierīci?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ja ieslēgsiet pakalpojumu <xliff:g id="SERVICE">%1$s</xliff:g>, ierīce neizmantos ekrāna bloķēšanu datu šifrēšanas uzlabošanai."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Pilnīga kontrole ir piemērota lietotnēm, kas nepieciešamas lietotājiem ar īpašām vajadzībām, taču ne lielākajai daļai lietotņu."</string> @@ -1815,8 +1817,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Atjaunināja administrators"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dzēsa administrators"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Labi"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Lai pagarinātu akumulatora darbības ilgumu, akumulatora jaudas taupīšanas režīmā tiek veiktas tālāk norādītās darbības.\n·Tiek ieslēgts tumšais motīvs.\n·Tiek izslēgtas vai ierobežotas darbības fonā, daži vizuālie efekti un citas funkcijas, piemēram, “Hey Google”.\n\n"<annotation id="url">"Uzzināt vairāk"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Lai pagarinātu akumulatora darbības ilgumu, akumulatora jaudas taupīšanas režīmā tiek veiktas tālāk norādītās darbības.\n·Tiek ieslēgts tumšais motīvs.\n·Tiek izslēgtas vai ierobežotas darbības fonā, daži vizuālie efekti un citas funkcijas, piemēram, “Hey Google”."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Lai samazinātu datu lietojumu, datu lietojuma samazinātājs neļauj dažām lietotnēm fonā nosūtīt vai saņemt datus. Lietotne, kuru pašlaik izmantojat, var piekļūt datiem, bet, iespējams, piekļūs tiem retāk (piemēram, attēli tiks parādīti tikai tad, kad tiem pieskarsieties)."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Vai ieslēgt datu lietojuma samazinātāju?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ieslēgt"</string> @@ -2072,13 +2076,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Paziņojumi"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Ātrie iestatījumi"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Barošanas dialoglodziņš"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Pārslēgt ekrāna sadalīšanu"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloķēt ekrānu"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekrānuzņēmums"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Pieejamības izvēlne"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> subtitru josla."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Pakotne “<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>” ir ievietota ierobežotā kopā."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Saruna"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupas saruna"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index f7e23a8ad1ac..51501b45335b 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -200,9 +200,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Уредот ќе се избрише"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Апликацијата на администраторот не може да се користи. Уредот ќе се избрише сега.\n\nАко имате прашања, контактирајте со администраторот на организацијата."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Печатењето е оневозможено од <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Деблокирајте лични апликации"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Блокирање на апликациите утре"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT-администраторот не дозволува паузирање на работниот профил за повеќе од <xliff:g id="DAYS">%1$d</xliff:g> дена"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Вклучи го работниот профил"</string> <string name="me" msgid="6207584824693813140">"Јас"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Опции на таблет"</string> @@ -1633,6 +1636,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ако ги задржите притиснати двете копчиња за јачина на звук неколку секунди, ќе се вклучи функцијата за пристапност <xliff:g id="SERVICE">%1$s</xliff:g>. Ова може да го промени начинот на функционирање на уредот.\n\nМоже да ја измените кратенкава да биде за друга функција во „Поставки > Пристапност“."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Вклучи"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Не вклучувај"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ВКЛУЧЕНО"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИСКЛУЧЕНО"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Дали дозволувате <xliff:g id="SERVICE">%1$s</xliff:g> да има целосна контрола врз вашиот уред?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ако вклучите <xliff:g id="SERVICE">%1$s</xliff:g>, уредот нема да го користи заклучувањето на екранот за да го подобри шифрирањето на податоците."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Целосната контрола е соодветна за апликации што ви помагаат со потребите за пристапност, но не и за повеќето апликации."</string> @@ -1794,8 +1799,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирано од администраторот"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избришано од администраторот"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Во ред"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"За да го продолжи траењето на батеријата, „Штедачот на батерија“:\n·вклучува темна тема\n·исклучува или ограничува активност во заднина, некои визуелни ефекти и други функции како „Hey Google“\n\n"<annotation id="url">"Дознајте повеќе"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"За да го продолжи траењето на батеријата, „Штедачот на батерија“:\n·вклучува „Темна тема“;\n·исклучува или ограничува активност во заднина, некои визуелни ефекти и други функции како „Ok Google“."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"За да се намали користењето интернет, „Штедачот на интернет“ спречува дел од апликациите да испраќаат или да примаат податоци во заднина. Одредена апликација што ја користите ќе може да користи интернет, но можеби тоа ќе го прави поретко. Ова значи, на пример, дека сликите нема да се прикажуваат додека не ги допрете."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Да се вклучи „Штедач на интернет“?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Вклучи"</string> @@ -2040,13 +2047,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Известувања"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Брзи поставки"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Дијалог за напојување"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Вклучи/исклучи поделен екран"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заклучен екран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Слика од екранот"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Мени за пристапност"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Насловна лента на <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е ставен во корпата ОГРАНИЧЕНИ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Разговор"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групен разговор"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 4d88c993d256..791117cb9bc6 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"നിങ്ങളുടെ ഉപകരണം മായ്ക്കും"</string> <string name="factory_reset_message" msgid="2657049595153992213">"അഡ്മിൻ ആപ്പ് ഉപയോഗിക്കാനാകില്ല. നിങ്ങളുടെ ഉപകരണം ഇപ്പോൾ മായ്ക്കപ്പെടും.\n\nനിങ്ങൾക്ക് ചോദ്യങ്ങൾ ഉണ്ടെങ്കിൽ, നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ അഡ്മിനെ ബന്ധപ്പെടുക."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> പ്രിന്റിംഗ് പ്രവർത്തനരഹിതമാക്കി."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"വ്യക്തിപര ആപ്പ് അൺബ്ലോക്കാക്കൂ"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ആപ്പുകൾ നാളെ ബ്ലോക്ക് ചെയ്യും"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ <xliff:g id="DAYS">%1$d</xliff:g> ദിവസത്തിൽ കൂടുതൽ താൽക്കാലികമായി നിർത്താൻ നിങ്ങളുടെ ഐടി അഡ്മിൻ അനുവദിക്കുന്നില്ല"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"ഔദ്യോഗിക പ്രൊഫൈൽ ഓണാക്കുക"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ ഓണാക്കുന്നത് വരെ നിങ്ങളുടെ വ്യക്തിപരമായ ആപ്പുകൾ ബ്ലോക്കായിരിക്കും"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"നിങ്ങളുടെ വ്യക്തിപര ആപ്പുകൾ നാളെ ബ്ലോക്ക് ചെയ്യും"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"ഔദ്യോഗിക പ്രൊഫൈൽ ഓണാക്കുക"</string> <string name="me" msgid="6207584824693813140">"ഞാന്"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ടാബ്ലെറ്റ് ഓപ്ഷനുകൾ"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"രണ്ട് വോളിയം കീകളും അൽപ്പ നേരത്തേക്ക് അമർത്തിപ്പിടിക്കുന്നത് ഉപയോഗസഹായി ഫീച്ചറായ <xliff:g id="SERVICE">%1$s</xliff:g> എന്നതിനെ ഓണാക്കുന്നു. നിങ്ങളുടെ ഉപകരണം പ്രവർത്തിക്കുന്ന വിധം ഇത് മാറ്റിയേക്കാം.\n\nക്രമീകരണം > ഉപയോഗസഹായി എന്നതിലെ മറ്റൊരു ഫീച്ചറിലേക്ക് നിങ്ങൾക്ക് ഈ കുറുക്കുവഴി മാറ്റാനാവും."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ഓണാക്കുക"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ഓണാക്കരുത്"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ഓണാണ്"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ഓഫാണ്"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> എന്നതിന് നിങ്ങളുടെ ഉപകരണത്തിന്മേൽ പൂർണ്ണ നിയന്ത്രണം അനുവദിക്കണോ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> ഓണാക്കിയെങ്കിൽ, ഡാറ്റ എൻക്രിപ്ഷൻ മെച്ചപ്പെടുത്താൻ ഉപകരണം നിങ്ങളുടെ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കില്ല."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ഉപയോഗസഹായി ആവശ്യങ്ങൾക്കായി നിങ്ങളെ സഹായിക്കുന്ന ആപ്പുകൾക്ക് പൂർണ്ണ നിയന്ത്രണം അനുയോജ്യമാണെങ്കിലും മിക്ക ആപ്പുകൾക്കും അനുയോജ്യമല്ല."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"നിങ്ങളുടെ അഡ്മിൻ അപ്ഡേറ്റ് ചെയ്യുന്നത്"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"നിങ്ങളുടെ അഡ്മിൻ ഇല്ലാതാക്കുന്നത്"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ശരി"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ബാറ്ററി ലെെഫ് വികസിപ്പിക്കാൻ, \'ബാറ്ററി ലാഭിക്കൽ\':\n ഡാർക്ക് തീം ഓണാക്കും\nപശ്ചാത്തല പ്രവർത്തനം, ചില വിഷ്വൽ ഇഫക്റ്റുകൾ, “ഹേയ് Google” പോലുള്ള മറ്റ് ഫീച്ചറുകൾ എന്നിവ ഓഫാക്കുകയോ നിയന്ത്രിക്കുകയോ ചെയ്യും\n\n"<annotation id="url">"കൂടുതലറിയുക"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ബാറ്ററി ലെെഫ് വികസിപ്പിക്കാൻ, \'ബാറ്ററി ലാഭിക്കൽ\':\n ഡാർക്ക് തീം ഓണാക്കും\nപശ്ചാത്തല പ്രവർത്തനം, ചില വിഷ്വൽ ഇഫക്റ്റുകൾ, “ഹേയ് Google” പോലുള്ള മറ്റ് ഫീച്ചറുകൾ എന്നിവ ഓഫാക്കുകയോ നിയന്ത്രിക്കുകയോ ചെയ്യും"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ഡാറ്റാ ഉപയോഗം കുറയ്ക്കാൻ സഹായിക്കുന്നതിനായി പശ്ചാത്തലത്തിൽ ഡാറ്റ അയയ്ക്കുകയോ സ്വീകരിക്കുകയോ ചെയ്യുന്നതിൽ നിന്ന് ചില ആപ്പുകളെ ഡാറ്റാ സേവർ തടയുന്നു. നിങ്ങൾ നിലവിൽ ഉപയോഗിക്കുന്ന ഒരു ആപ്പിന് ഡാറ്റ ആക്സസ് ചെയ്യാനാകും, എന്നാൽ വല്ലപ്പോഴും മാത്രമെ സംഭവിക്കുന്നുള്ളു. ഇതിനർത്ഥം, ഉദാഹരണമായി നിങ്ങൾ ടാപ്പ് ചെയ്യുന്നത് വരെ ചിത്രങ്ങൾ പ്രദർശിപ്പിക്കുകയില്ല എന്നാണ്."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ഡാറ്റ സേവർ ഓണാക്കണോ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ഓണാക്കുക"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"അറിയിപ്പുകൾ"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ദ്രുത ക്രമീകരണം"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"പവർ ഡയലോഗ്"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"സ്ക്രീൻ വിഭജന മോഡ് മാറ്റുക"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ലോക്ക് സ്ക്രീൻ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"സ്ക്രീൻഷോട്ട്"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ഉപയോഗസഹായി മെനു"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിന്റെ അടിക്കുറിപ്പ് ബാർ."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> നിയന്ത്രിത ബക്കറ്റിലേക്ക് നീക്കി"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"സംഭാഷണം"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ഗ്രൂപ്പ് സംഭാഷണം"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index f9963435bbaf..f7ac0696af58 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Таны төхөөрөмж устах болно."</string> <string name="factory_reset_message" msgid="2657049595153992213">"Админ аппыг ашиглах боломжгүй. Таны төхөөрөмжийг одоо устгана.\n\nХэрэв танд асуулт байгаа бол байгууллагынхаа админтай холбогдоно уу."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> хэвлэх үйлдлийг идэвхгүй болгосон."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Хувийн аппуудаа блокоос гаргана уу"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Аппуудыг маргааш блоклоно"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Таны мэдээлэл технологийн админ таны ажлын профайлыг <xliff:g id="DAYS">%1$d</xliff:g>-с олон хоног түр зогсоохыг зөвшөөрөхгүй байна"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Ажлын профайлаа асаах"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Та ажлын профайлыг асаах хүртэл таны хувийн аппуудыг хориглосон"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Таны хувийн аппуудыг маргааш хориглоно"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Ажлын профайлыг асаах"</string> <string name="me" msgid="6207584824693813140">"Би"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Таблетын сонголтууд"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Дууны түвшний түлхүүрийг хэдэн секундийн турш зэрэг дарах нь хандалтын онцлог болох <xliff:g id="SERVICE">%1$s</xliff:g>-г асаадаг. Энэ нь таны төхөөрөмжийн ажиллах зарчмыг өөрчилж болзошгүй.\n\nТа Тохиргоо > Хандалт хэсэгт энэ товчлолыг өөр онцлогт оноож өөрчлөх боломжтой."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Асаах"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Битгий асаа"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ИДЭВХТЭЙ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИДЭВХГҮЙ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>-д таны төхөөрөмжийг бүрэн хянахыг зөвшөөрөх үү?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Хэрэв та <xliff:g id="SERVICE">%1$s</xliff:g>-г асаавал таны төхөөрөмж өгөгдлийн шифрлэлтийг сайжруулахын тулд таны дэлгэцийн түгжээг ашиглахгүй."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Бүрэн хянах нь таны хандалтын үйлчилгээний шаардлагад тусалдаг аппуудад тохиромжтой боловч ихэнх аппад тохиромжгүй байдаг."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Таны админ шинэчилсэн"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Таны админ устгасан"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгч нь:\n·Бараан загварыг асаадаг\n·Арын үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг бусад онцлогийг унтрааж эсвэл хязгаарладаг\n\n"<annotation id="url">"Нэмэлт мэдээлэл авах"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгч нь:\n·Бараан загварыг асаадаг\n·Арын үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг бусад онцлогийг унтрааж эсвэл хязгаарладаг"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Дата ашиглалтыг багасгахын тулд дата хэмнэгч нь ар талд ажиллаж буй зарим апп-н өгөгдлийг илгээх болон авахаас сэргийлдэг. Таны одоогийн ашиглаж буй апп нь өгөгдөлд хандах боломжтой хэдий ч тогтмол хандахгүй. Энэ нь жишээлбэл зургийг товших хүртэл харагдахгүй гэсэн үг юм."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Дата хэмнэгчийг асаах уу?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Асаах"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Мэдэгдэл"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Шуурхай тохиргоо"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Тэжээлийн харилцах цонх"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Дэлгэц хуваахыг унтраах/асаах"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Дэлгэцийг түгжих"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Дэлгэцийн зураг дарах"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Хандалтын цэс"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н гарчгийн талбар."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>-г ХЯЗГААРЛАСАН сагс руу орууллаа"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Харилцан яриа"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Бүлгийн харилцан яриа"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index c46cb8d97527..d842abdad39d 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"तुमचे डिव्हाइस मिटविले जाईल"</string> <string name="factory_reset_message" msgid="2657049595153992213">"प्रशासक अॅप वापरता येणार नाही. तुमचे डिव्हाइस आता साफ केले जाईल.\n\nतुम्हाला कुठलेही प्रश्न असल्यास, तुमच्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> नी प्रिंट करणे बंद केले आहे."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"वैयक्तिक ॲप्स अनब्लॉक करा"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"अॅप्स उद्या ब्लॉक केली जातील"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"तुमचा आयटी अॅडमिन तुमची ऑफिस प्रोफाइल <xliff:g id="DAYS">%1$d</xliff:g> पेक्षा जास्त दिवसांसाठी थांबवण्याची अनुमती देत नाही"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"तुमची कार्य प्रोफाइल सुरू करा"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"तुम्ही तुमची कार्य प्रोफाइल सुरू करेपर्यंत तुमची वैयक्तिक ॲप्स ब्लॉक केली आहेत"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"तुमची वैयक्तिक ॲप्स उद्या ब्लॉक केली जातील"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"ऑफिस प्रोफाइल सुरू करा"</string> <string name="me" msgid="6207584824693813140">"मी"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"टॅबलेट पर्याय"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"दोन्ही व्हॉल्यूम की काही सेकंद धरून ठेवल्याने <xliff:g id="SERVICE">%1$s</xliff:g>, एक अॅक्सेसिबिलिटी वैशिष्ट्य सुरू होते. यामुळे तुमचे डिव्हाइस कसे काम करते हे पूर्णपणे बदलते.\n\nतुम्ही हा शॉर्टकट सेटिंग्ज > अॅक्सेसिबिलिटी मध्ये बदलू शकता."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"सुरू करा"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"सुरू करू नका"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"सुरू आहे"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"बंद आहे"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> ला तुमचे डिव्हाइसच संपूर्णपणे नियंत्रित करायची अनुमती द्यायची का?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"तुम्ही <xliff:g id="SERVICE">%1$s</xliff:g> सुरू केल्यास, तुमचे डिव्हाइस डेटा एंक्रिप्शनमध्ये सुधारणा करण्यासाठी स्क्रीन लॉक वापरणार नाही."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"जी ॲप्स तुमच्या ॲक्सेसिबिलिटी गरजा पूर्ण करतात अशा ॲप्ससाठी संपूर्ण नियंत्रण योग्य आहे. पण ते सर्व ॲप्सना लागू होईल असे नाही."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"आपल्या प्रशासकाने अपडेट केले"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"आपल्या प्रशासकाने हटवले"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ओके"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"बॅटरी सेव्हर हे बॅटरीचे आयुष्य वाढवते:\n·गडद थीम सुरू करते \n· बॅकग्राउंड अॅक्टिव्हिटी, काही व्हिज्युअल इफेक्ट आणि \"Ok Google\" यासारखी वैशिष्ट्ये बंद किंवा मर्यादित करते.\n\n"<annotation id="url">"अधिक जाणून घ्या"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"बॅटरीचे आयुष्य वाढवण्यासाठी बॅटरी सेव्हर:\n·गडद थीम सुरू करते \n· बॅकग्राउंड अॅक्टिव्हिटी, काही व्हिज्युअल इफेक्ट आणि \"Ok Google\" यासारखी वैशिष्ट्ये बंद किंवा मर्यादित करते."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"डेटाचा वापर कमी करण्यात मदत करण्यासाठी काही अॅप्सना बॅकग्राउंडमध्ये डेटा पाठवण्यास किंवा मिळवण्यास डेटा सर्व्हर प्रतिबंध करतो. तुम्ही सध्या वापरत असलेले अॅप डेटा अॅक्सेस करू शकते, पण तसे खूप कमी वेळा होते. याचाच अर्थ असा की, तुम्ही इमेजवर टॅप करेपर्यंत त्या डिस्प्ले होणार नाहीत असे होऊ शकते."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"डेटा सेव्हर चालू करायचे?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"चालू करा"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"सूचना"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"क्विक सेटिंग्ज"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"पॉवर डायलॉग"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"विभाजित स्क्रीन टॉगल करा"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"स्क्रीन लॉक करा"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रीनशॉट"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"अॅक्सेसिबिलिटी मेनू"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> चा शीर्षक बार."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> हे प्रतिबंधित बादलीमध्ये ठेवण्यात आले आहे"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"संभाषण"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"गट संभाषण"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 8a4148a91d6a..2364c0aaa56d 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Peranti anda akan dipadam"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Apl pentadbir tidak dapat digunakan. Peranti anda akan dipadamkan sekarang.\n\nJika anda ingin mengemukakan soalan, hubungi pentadbir organisasi anda."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Pencetakan dilumpuhkan oleh <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Nyahsekat apl peribadi anda"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apl akan disekat esok"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Pentadbir IT anda tidak membenarkan profil kerja anda dijeda melebihi <xliff:g id="DAYS">%1$d</xliff:g> hari"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Hidupkan profil kerja anda"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Apl peribadi anda disekat sehingga anda menghidupkan profil kerja"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Apl peribadi anda akan disekat esok"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Hidupkan profil kerja"</string> <string name="me" msgid="6207584824693813140">"Saya"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Pilihan tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Tindakan menahan kedua-dua kekunci kelantangan selama beberapa saat akan menghidupkan <xliff:g id="SERVICE">%1$s</xliff:g>, iaitu satu ciri kebolehaksesan. Ini mungkin mengubah cara peranti anda berfungsi.\n\nAnda boleh menukar pintasan ini kepada ciri lain dalam Tetapan > Kebolehaksesan."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Hidupkan"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Jangan hidupkan"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"HIDUP"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"MATI"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Benarkan <xliff:g id="SERVICE">%1$s</xliff:g> mempunyai kawalan penuh atas peranti anda?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jika anda menghidupkan <xliff:g id="SERVICE">%1$s</xliff:g>, peranti anda tidak akan menggunakan kunci skrin anda untuk meningkatkan penyulitan data."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kawalan penuh sesuai untuk apl yang membantu anda dengan keperluan kebolehaksesan tetapi bukan untuk kebanyakan apl."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Dikemas kini oleh pentadbir anda"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dipadamkan oleh pentadbir anda"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Untuk melanjutkan hayat bateri, Penjimat Bateri:\n·Menghidupkan Tema gelap\n·Mematikan atau mengehadkan aktiviti latar belakang, sesetengah kesan visual dan ciri lain seperti “Hey Google”\n\n"<annotation id="url">"Ketahui lebih lanjut"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Untuk melanjutkan hayat bateri, Penjimat Bateri:\n·Menghidupkan Tema gelap\n·Mematikan atau mengehadkan aktiviti latar belakang, sesetengah kesan visual dan ciri lain seperti “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Untuk membantu mengurangkan penggunaan data, Penjimat Data menghalang sesetengah apl daripada menghantar atau menerima data di latar. Apl yang sedang digunakan boleh mengakses data tetapi mungkin tidak secara kerap. Perkara ini mungkin bermaksud bahawa imej tidak dipaparkan sehingga anda mengetik pada imej itu, contohnya."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Hidupkan Penjimat Data?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Hidupkan"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Pemberitahuan"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Tetapan Pantas"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialog Kuasa"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Togol Skrin Pisah"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Skrin Kunci"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Tangkapan skrin"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu Kebolehaksesan"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Bar kapsyen <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah diletakkan dalam baldi TERHAD"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Perbualan"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Perbualan Kumpulan"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 7c6f3e72f9cc..17b7c7c5f121 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string> <string name="factory_reset_message" msgid="2657049595153992213">"စီမံခန့်ခွဲမှု အက်ပ်ကို သုံး၍မရပါ။ သင်၏ စက်ပစ္စည်းအတွင်းရှိ အရာများကို ဖျက်လိုက်ပါမည်\n\nမေးစရာများရှိပါက သင့်အဖွဲ့အစည်း၏ စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> က ပုံနှိပ်ထုတ်ယူခြင်းကို ပိတ်ထားသည်။"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ကိုယ်ပိုင်အက်ပ်ပြန်ဖွင့်ခြင်း"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"အက်များကို မနက်ဖြန်ပိတ်မည်"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"သင့်အလုပ်ပရိုဖိုင်ကို <xliff:g id="DAYS">%1$d</xliff:g> ရက်ထက်ပိုပြီး ခဏရပ်ထားရန် သင်၏ IT စီမံခန့်ခွဲသူက ခွင့်မပြုပါ"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"သင့်အလုပ်ပရိုဖိုင် ဖွင့်ခြင်း"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"သင့်အလုပ်ပရိုဖိုင် ဖွင့်သည်အထိ ကိုယ်ပိုင်အက်ပ်များကို ပိတ်ထားသည်"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"သင့်ကိုယ်ပိုင်အက်ပ်များကို မနက်ဖြန် ပိတ်လိုက်ပါမည်"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"အလုပ်ပရိုဖိုင် ဖွင့်ရန်"</string> <string name="me" msgid="6207584824693813140">"ကျွန်ုပ်"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tabletဆိုင်ရာရွေးချယ်မှုများ"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"အသံခလုတ်နှစ်ခုလုံးကို စက္ကန့်အနည်းငယ် ဖိထားခြင်းက အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှုဖြစ်သော <xliff:g id="SERVICE">%1$s</xliff:g> ကို ဖွင့်ပေးသည်။ ဤလုပ်ဆောင်ချက်က သင့်စက်အလုပ်လုပ်ပုံကို ပြောင်းလဲနိုင်သည်။\n\nဤဖြတ်လမ်းလင့်ခ်ကို \'ဆက်တင်များ > အများသုံးစွဲနိုင်မှု\' တွင် နောက်ဝန်ဆောင်မှုတစ်ခုသို့ ပြောင်းနိုင်သည်။"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ဖွင့်ရန်"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"မဖွင့်ပါနှင့်"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ဖွင့်ထားသည်"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ပိတ်ထားသည်"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> ကို သင့်စက်အား အပြည့်အဝထိန်းချုပ်ခွင့် ပေးလိုပါသလား။"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> ဖွင့်လိုက်ပါက သင်၏စက်သည် ဒေတာအသွင်ဝှက်ခြင်း ပိုကောင်းမွန်စေရန် သင့်ဖန်သားပြင်လော့ခ်ကို သုံးမည်မဟုတ်ပါ။"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"အများသုံးစွဲနိုင်မှု လိုအပ်ချက်များအတွက် အထောက်အကူပြုသည့် အက်ပ်များကို အပြည့်အဝထိန်းချုပ်ခြင်းသည် သင့်လျော်သော်လည်း အက်ပ်အများစုအတွက် မသင့်လျော်ပါ။"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"သင်၏ စီမံခန့်ခွဲသူက အပ်ဒိတ်လုပ်ထားသည်"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"သင်၏ စီမံခန့်ခွဲသူက ဖျက်လိုက်ပါပြီ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ဘက်ထရီသက်တမ်း ပိုရှည်စေရန် \'ဘက်ထရီအားထိန်း\' က \n·မှောင်သည့် အပြင်အဆင်ကို ဖွင့်သည် \n·နောက်ခံလုပ်ဆောင်ချက် အချို့ အမြင်အာရုံဆိုင်ရာ အထူးပြုလုပ်ချက်များနှင့် “Hey Google” ကဲ့သို့ အခြား ဝန်ဆောင်မှုများကို ပိတ်ခြင်း သို့မဟုတ် ကန့်သတ်ခြင်းတို့ ပြုလုပ်သည်။\n\n"<annotation id="url">"ပိုမိုလေ့လာရန်"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ဘက်ထရီသက်တမ်း ပိုရှည်စေရန် \'ဘက်ထရီအားထိန်း\' က- \n·မှောင်သည့် အပြင်အဆင်ကို ဖွင့်သည်\n·နောက်ခံလုပ်ဆောင်ချက်၊ ပြသမှုဆိုင်ရာ အထူးပြုလုပ်ချက်အချို့နှင့် “Hey Google” ကဲ့သို့ အခြား ဝန်ဆောင်မှုများကို ပိတ်သည် သို့မဟုတ် ကန့်သတ်သည်။"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ဒေတာအသုံးလျှော့ချနိုင်ရန်အတွက် အက်ပ်များကို နောက်ခံတွင် ဒေတာပို့ခြင်းနှင့် လက်ခံခြင်းမပြုရန် \'ဒေတာချွေတာမှု\' စနစ်က တားဆီးထားပါသည်။ ယခုအက်ပ်ဖြင့် ဒေတာအသုံးပြုနိုင်သော်လည်း အကြိမ်လျှော့၍သုံးရပါမည်။ ဥပမာ၊ သင်က မတို့မချင်း ပုံများပေါ်လာမည် မဟုတ်ပါ။"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ဒေတာချွေတာမှုစနစ် ဖွင့်မလား။"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ဖွင့်ပါ"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"အကြောင်းကြားချက်များ"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"အမြန် ဆက်တင်များ"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ပါဝါ ဒိုင်ယာလော့"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းကို နှိပ်ပါ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"လော့ခ်မျက်နှာပြင်"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ဖန်သားပြင်ဓာတ်ပုံ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"အများသုံးစွဲနိုင်မှု မီနူး"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>၏ ခေါင်းစီး ဘား။"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ကို တားမြစ်ထားသော သိမ်းဆည်းမှုအတွင်းသို့ ထည့်ပြီးပါပြီ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>-"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"စကားဝိုင်း"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"အဖွဲ့စကားဝိုင်း"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 9f75ce2217f2..5b7787f0f9db 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten blir slettet"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Administratorappen kan ikke brukes. Enheten din blir nå tømt.\n\nTa kontakt med administratoren for organisasjonen din hvis du har spørsmål."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> har slått av utskrift."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Ikke blokkér personlige apper"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apper blir blokkert i morgen"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT-administratoren din tillater ikke at jobbprofilen din blir satt på pause i mer enn <xliff:g id="DAYS">%1$d</xliff:g> dager"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Slå på jobbprofilen din"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"De personlige appene dine er blokkert til du slår på jobbprofilen din"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"De personlige appene dine blokkeres i morgen"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Slå på jobbprofilen"</string> <string name="me" msgid="6207584824693813140">"Meg"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Innstillinger for nettbrettet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hvis du holder inne begge volumtastene i noen sekunder, slår du på <xliff:g id="SERVICE">%1$s</xliff:g>, en tilgjengelighetsfunksjon. Dette kan endre hvordan enheten din fungerer.\n\nDu kan endre denne snarveien til en annen funksjon i Innstillinger > Tilgjengelighet."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Slå på"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ikke slå på"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"PÅ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vil du gi <xliff:g id="SERVICE">%1$s</xliff:g> full kontroll over enheten din?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Hvis du slår på <xliff:g id="SERVICE">%1$s</xliff:g>, bruker ikke enheten skjermlåsen til å forbedre datakryptering."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full kontroll er passende for apper som hjelper deg med tilgjengelighetsbehov, men ikke for de fleste apper."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Oppdatert av administratoren din"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet av administratoren din"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"For å forlenge batterilevetiden slår Batterisparing\n·på mørkt tema\n·av eller begrenser bakgrunnsaktivitet, enkelte visuelle effekter og andre funksjoner, for eksempel «Hey Google»\n\n"<annotation id="url">"Finn ut mer"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"For å forlenge batterilevetiden slår Batterisparing\n·på mørkt tema\n·av eller begrenser bakgrunnsaktivitet, enkelte visuelle effekter og andre funksjoner, for eksempel «Hey Google»"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Datasparing hindrer noen apper fra å sende og motta data i bakgrunnen, for å redusere dataforbruket. Aktive apper kan bruke data, men kanskje ikke så mye som ellers – for eksempel vises ikke bilder før du trykker på dem."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Vil du slå på Datasparing?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Slå på"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Varsler"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Hurtiginnstillinger"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialogboks for å slå av/på"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Slå delt skjerm av/på"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låseskjerm"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjermdump"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Tilgjengelighet-meny"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Tekstingsfelt i <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blitt plassert i TILGANGSBEGRENSET-toppmappen"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Samtale"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Gruppesamtale"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 81115f835f8f..c592c75f5fc5 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"तपाईंको यन्त्र मेटिनेछ"</string> <string name="factory_reset_message" msgid="2657049595153992213">"प्रशासकको एप प्रयोग गर्न मिल्दैन। तपाईंको यन्त्रको डेटा अब मेटाइने छ।\n\nतपाईंसँग प्रश्नहरू भएका खण्डमा आफ्नो संगठनका प्रशासकसँग सम्पर्क गर्नुहोस्।"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ले छाप्ने कार्यलाई असक्षम पार्यो।"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"आफ्ना व्यक्तिगत एपमाथिको रोक हटाउनु"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"भोलि एपहरूलाई रोक लगाइने छ"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"तपाईंका IT एडमिनले तपाईंको कार्यसम्बन्धी प्रोफाइल <xliff:g id="DAYS">%1$d</xliff:g> दिनभन्दा बढी पज गर्ने अनुमति दिनुभएको छैन"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"आफ्नो कार्य प्रोफाइल सक्रिय गर्नुहोस्"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"तपाईंले आफ्नो कार्य प्रोफाइल सक्रिय नगरुन्जेल तपाईंका व्यक्तिगत अनुप्रयोगहरूलाई रोक लगाइन्छ"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"तपाईंका व्यक्तिगत अनुप्रयोगहरूलाई भोलि रोक लगाइने छ"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"कार्यसम्बन्धी प्रोफाइल सक्रिय गर्नुहोस्"</string> <string name="me" msgid="6207584824693813140">"मलाई"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ट्याब्लेट विकल्पहरू"</string> @@ -1637,6 +1637,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुले <xliff:g id="SERVICE">%1$s</xliff:g> नामक पहुँचसम्बन्धी सुविधा सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nतपाईं सेटिङ > पहुँचमा गई यो सर्टकटमार्फत अर्को सुविधा खुल्ने बनाउन सक्नुहुन्छ।"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"सक्रिय गरियोस्"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"सक्रिय नगरियोस्"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"सक्रिय"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"निष्क्रिय"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> लाई तपाईंको यन्त्र पूर्ण रूपमा नियन्त्रण गर्न दिने हो?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"तपाईंले <xliff:g id="SERVICE">%1$s</xliff:g> सक्रिय गर्नुभयो भने तपाईंको यन्त्रले डेटा इन्क्रिप्ट गर्ने सुविधाको स्तरोन्नति गर्न तपाईंको स्क्रिन लक सुविधाको प्रयोग गर्ने छैन।"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"तपाईंलाई पहुँच राख्न आवश्यक पर्ने कुरामा सहयोग गर्ने अनुप्रयोगहरूमाथि पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश अनुप्रयोगहरूका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string> @@ -1798,8 +1800,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"तपाईंका प्रशासकले अद्यावधिक गर्नुभएको"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"तपाईंका प्रशासकले मेट्नुभएको"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ठिक छ"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ब्याट्रीको आयु लामो बनाउन ब्याट्री सेभरले:\n·अँध्यारो थिम सक्रिय गर्छ\n·पृष्ठभूमिका गतिविधि, कतिपय भिजुअल प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू निष्क्रिय वा सीमित पार्छ।\n\n"<annotation id="url">"थप जान्नुहोस्"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ब्याट्रीको आयु बढाउन ब्याट्री सेभरले:\n·अँध्यारो थिम सक्रिय गर्छ\n·पृष्ठभूमिका गतिविधि, कतिपय भिजुअल प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू निष्क्रिय वा सीमित पार्छ।"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"डेटाको प्रयोगलाई कम गर्न डेटा सर्भरले केही अनुप्रयोगलाई पृष्ठभूमिमा डेटा पठाउन वा प्राप्त गर्न दिँदैन। तपाईंले हाल प्रयोग गरिरहनुभएको अनु्प्रयोगले डेटा चलाउन सक्छ, तर पहिला भन्दा कम अन्तरालमा मात्र। उदाहरणका लागि, तपाईले छविहरूमा ट्याप नगरेसम्म ती छविहरू देखिँदैनन्।"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"डेटा सेभर सक्रिय गर्ने हो?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"सक्रिय गर्नुहोस्"</string> @@ -2044,13 +2048,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"सूचनाहरू"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"द्रुत सेटिङहरू"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"पावर संवाद"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"विभाजित स्क्रिन टगल गर्नुहोस्"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"लक स्क्रिन"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रिनसट"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"पहुँचसम्बन्धी मेनु"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> को क्याप्सन बार।"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> लाई प्रतिबन्धित बाल्टीमा राखियो"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"वार्तालाप"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"सामूहिक वार्तालाप"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 17989bff6ebc..f834adefe6b9 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Je apparaat wordt gewist"</string> <string name="factory_reset_message" msgid="2657049595153992213">"De beheer-app kan niet worden gebruikt. Je apparaat wordt nu gewist.\n\nNeem contact op met de beheerder van je organisatie als je vragen hebt."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Afdrukken uitgeschakeld door <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Blokkering van je persoonlijke apps opheffen"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Apps worden morgen geblokkeerd"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Je IT-beheerder staat niet toe dat je werkprofiel meer dan <xliff:g id="DAYS">%1$d</xliff:g> dagen wordt onderbroken"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Schakel je werkprofiel in"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Je persoonlijke apps zijn geblokkeerd totdat je je werkprofiel inschakelt"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Je persoonlijke apps worden morgen geblokkeerd"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Werkprofiel inschakelen"</string> <string name="me" msgid="6207584824693813140">"Ik"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tabletopties"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Als je beide volumetoetsen een paar seconden ingedrukt houdt, wordt de toegankelijkheidsfunctie <xliff:g id="SERVICE">%1$s</xliff:g> ingeschakeld. Hierdoor kan de manier veranderen waarop je apparaat werkt.\n\nJe kunt deze sneltoets op een andere functie instellen via Instellingen > Toegankelijkheid."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Inschakelen"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Niet inschakelen"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AAN"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"UIT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Toestaan dat <xliff:g id="SERVICE">%1$s</xliff:g> volledige controle over je apparaat heeft?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Als je <xliff:g id="SERVICE">%1$s</xliff:g> inschakelt, maakt je apparaat geen gebruik van schermvergrendeling om de gegevensversleuteling te verbeteren."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Volledige controle is gepast voor apps die je helpen met toegankelijkheid, maar voor de meeste apps is het ongepast."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Geüpdatet door je beheerder"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Verwijderd door je beheerder"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Batterijbesparing doet het volgende om de batterijduur te verlengen:\n·Het donkere thema inschakelen\n·Achtergrondactiviteit, bepaalde visuele effecten en andere functies (zoals \'Hey Google\') uitschakelen of beperken\n\n"<annotation id="url">"Meer informatie"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Batterijbesparing doet het volgende om de batterijduur te verlengen:\n Het donkere thema aanzetten\n·Achtergrondactiviteit, bepaalde visuele effecten en andere functies (zoals \'Hey Google\') uitzetten of beperken"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Databesparing beperkt het datagebruik door te voorkomen dat sommige apps gegevens verzenden of ontvangen op de achtergrond. De apps die je open hebt, kunnen nog steeds data verbruiken, maar doen dit minder vaak. Afbeeldingen worden dan bijvoorbeeld niet weergegeven totdat je erop tikt."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Databesparing aanzetten?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Inschakelen"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Meldingen"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Snelle instellingen"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Voedingsdialoogvenster"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Gesplitst scherm schakelen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Scherm vergrendelen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Toegankelijkheidsmenu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Ondertitelingsbalk van <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in de bucket RESTRICTED geplaatst"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Gesprek"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Groepsgesprek"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index a77845f10e93..24b4e2e16538 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ବର୍ତ୍ତମାନ ଲିଭାଯିବ"</string> <string name="factory_reset_message" msgid="2657049595153992213">"ଆଡମିନ୍ ଆପ୍ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଆପଣଙ୍କ ଡିଭାଇସ୍ର ସମସ୍ତ ଡାଟାକୁ ବର୍ତ୍ତମାନ ଲିଭାଇଦିଆଯିବ। \n\nଯଦି ଆପଣଙ୍କର କୌଣସି ପ୍ରଶ୍ନ ରହିଥାଏ, ଆପଣଙ୍କ ସଂସ୍ଥାର ଆଡମିନ୍ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ଦ୍ଵାରା ପ୍ରିଣ୍ଟିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଆପ ଅନବ୍ଲକ କର"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ଆସନ୍ତାକାଲି ଆପ୍ସ ବ୍ଲକ୍ ହୋଇଯିବ"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"ଆପଣଙ୍କ IT ଆଡମିନ୍ ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲକୁ <xliff:g id="DAYS">%1$d</xliff:g>ରୁ ଅଧିକ ଦିନ ପାଇଁ ବିରତ କରିବାକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଚାଲୁ କରନ୍ତୁ"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"ଆପଣ ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଚାଲୁ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଆପଣଙ୍କର ବ୍ୟକ୍ତିଗତ ଆପ୍ସ ବ୍ଲକ୍ କରାଯାଇଛି"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"ଆସନ୍ତାକାଲି ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଆପ୍ସକୁ ବ୍ଲକ୍ କରାଯିବ"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଚାଲୁ କରନ୍ତୁ"</string> <string name="me" msgid="6207584824693813140">"ମୁଁ"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ଟାବଲେଟ୍ର ବିକଳ୍ପ"</string> @@ -1108,7 +1108,7 @@ <string name="inputMethod" msgid="1784759500516314751">"ଇନପୁଟ୍ ପଦ୍ଧତି"</string> <string name="editTextMenuTitle" msgid="857666911134482176">"ଟେକ୍ସଟ୍ କାର୍ଯ୍ୟ"</string> <string name="low_internal_storage_view_title" msgid="9024241779284783414">"ଷ୍ଟୋରେଜ୍ ସ୍ପେସ୍ ଶେଷ ହେବାରେ ଲାଗିଛି"</string> - <string name="low_internal_storage_view_text" msgid="8172166728369697835">"କିଛି ସିଷ୍ଟମ ଫଙ୍କଶନ୍ କାମ କରିନପାରେ"</string> + <string name="low_internal_storage_view_text" msgid="8172166728369697835">"କିଛି ସିଷ୍ଟମ ପ୍ରକାର୍ଯ୍ୟ କାମ କରିନପାରେ"</string> <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"ସିଷ୍ଟମ୍ ପାଇଁ ପ୍ରର୍ଯ୍ୟାପ୍ତ ଷ୍ଟୋରେଜ୍ ନାହିଁ। ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ଆପଣଙ୍କ ପାଖରେ 250MB ଖାଲି ଜାଗା ଅଛି ଏବଂ ପୁନଃ ଆରମ୍ଭ କରନ୍ତୁ।"</string> <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string> <string name="app_running_notification_text" msgid="5120815883400228566">"ଅଧିକ ସୂଚନା ପାଇଁ କିମ୍ବା ଆପ୍ ବନ୍ଦ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> @@ -1631,6 +1631,10 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"କିଛି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍ କୀ’କୁ ଧରି ରଖିବା ଫଳରେ ଏକ ଆକ୍ସେସିବିଲିଟୀ ଫିଚର୍ <xliff:g id="SERVICE">%1$s</xliff:g> ଚାଲୁ ହୁଏ। ଏହା ଆପଣଙ୍କ ଡିଭାଇସ୍ କିପରି କାମ କରେ ତାହା ପରିବର୍ତ୍ତନ କରିପାରେ।\n\nଆପଣ ସେଟିଂସ୍ &gt ଆକ୍ସେସିବିଲିଟୀରେ ଏହି ସର୍ଚକଟକୁ ଅନ୍ୟ ଏକ ଫିଚରରେ ପରିବର୍ତ୍ତନ କରିପାରିବେ।"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ଚାଲୁ କରନ୍ତୁ"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ଚାଲୁ କରନ୍ତୁ ନାହିଁ"</string> + <!-- no translation found for accessibility_shortcut_menu_item_status_on (6608392117189732543) --> + <skip /> + <!-- no translation found for accessibility_shortcut_menu_item_status_off (5531598275559472393) --> + <skip /> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>କୁ ଆପଣଙ୍କ ଡିଭାଇସର ସମ୍ପୂର୍ଣ୍ଣ ନିୟନ୍ତ୍ରଣର ଅନୁମତି ଦେବେ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"ଯଦି ଆପଣ <xliff:g id="SERVICE">%1$s</xliff:g> ଚାଲୁ କରନ୍ତି, ତେବେ ଆପଣଙ୍କ ଡିଭାଇସ୍ ଡାଟା ଏନକ୍ରିପ୍ସନ୍ ବୃଦ୍ଧି କରିବାକୁ ଆପଣଙ୍କର ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରିବ ନାହିଁ।"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ଯେଉଁ ଆପ୍ସ ଆପଣଙ୍କୁ ଆକ୍ସେସିବିଲିଟୀ ଆବଶ୍ୟକତାରେ ସହାୟତା କରେ, ସେହି ଆପ୍ସ ପାଇଁ ସମ୍ପୂର୍ଣ୍ଣ ନିୟନ୍ତ୍ରଣ ଉପଯୁକ୍ତ ଅଟେ, କିନ୍ତୁ ଅଧିକାଂଶ ଆପ୍ସ ପାଇଁ ଉପଯୁକ୍ତ ନୁହେଁ।"</string> @@ -1792,8 +1796,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"ଆପଣଙ୍କ ଆଡମିନ୍ ଅପଡେଟ୍ କରିଛନ୍ତି"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ଆପଣଙ୍କ ଆଡମିନ୍ ଡିଲିଟ୍ କରିଛନ୍ତି"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ଠିକ୍ ଅଛି"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ବ୍ୟାଟେରୀ ଜୀବନ ବଢ଼ାଇବାକୁ ବ୍ୟାଟେରୀ ସେଭର୍:\n·ଗାଢା ଥିମ୍ ଚାଲୁ କରେ\n·ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପକୁ, କିଛି ଭିଜୁଆଲ୍ ପ୍ରଭାବଗୁଡ଼ିକୁ ଏବଂ “ହେ Google” ପରି ଅନ୍ୟ ଫିଚର୍କୁ ବନ୍ଦ ରଖେ କିମ୍ବା ପ୍ରତିବନ୍ଧିତ କରିଥାଏ\n\n"<annotation id="url">"ଅଧିକ ଜାଣନ୍ତୁ"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ବ୍ୟାଟେରୀ ଜୀବନ ବଢ଼ାଇବାକୁ ବ୍ୟାଟେରୀ ସେଭର୍:\n·ଗାଢା ଥିମ୍ ଚାଲୁ କରେ\n·ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପକୁ, କିଛି ଭିଜୁଆଲ୍ ପ୍ରଭାବଗୁଡ଼ିକୁ ଏବଂ “ହେ Google” ପରି ଅନ୍ୟ ଫିଚର୍କୁ ବନ୍ଦ ରଖେ କିମ୍ବା ପ୍ରତିବନ୍ଧିତ କରିଥାଏ"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ଡାଟା ବ୍ୟବହାର କମ୍ କରିବାରେ ସାହାଯ୍ୟ କରିବାକୁ, ଡାଟା ସେଭର୍ ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡରେ ଡାଟା ପଠାଇବା କିମ୍ବା ପ୍ରାପ୍ତ କରିବାକୁ କିଛି ଆପ୍କୁ ବାରଣ କରେ। ଆପଣ ବର୍ତ୍ତମାନ ବ୍ୟବହାର କରୁଥିବା ଆପ୍, ଡାଟା ଆକ୍ସେସ୍ କରିପାରେ, କିନ୍ତୁ ଏହା କମ୍ ଥର କରିପାରେ। ଏହାର ଅର୍ଥ ହୋଇପାରେ ଯେମିତି ଆପଣ ଟାପ୍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଇମେଜ୍ ଡିସପ୍ଲେ ହୁଏ ନାହିଁ।"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ଡାଟା ସେଭର୍ ଚାଲୁ କରିବେ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ଅନ୍ କରନ୍ତୁ"</string> @@ -2038,13 +2044,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"କ୍ୱିକ୍ ସେଟିଂସ୍ ଖୋଲନ୍ତୁ"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ପାୱାର ଡାୟଲଗ୍ ଖୋଲନ୍ତୁ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ଦୁଇଟି ସ୍କ୍ରିନ୍ ମଧ୍ୟରେ ଟୋଗଲ୍ କରନ୍ତୁ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ସ୍କ୍ରିନ୍ ଲକ୍ କରନ୍ତୁ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ସ୍କ୍ରିନ୍ସଟ୍ ନିଅନ୍ତୁ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ଆକ୍ସେସିବିଲିଟୀ ମେନୁ"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>ର କ୍ୟାପ୍ସନ୍ ବାର୍।"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>କୁ ପ୍ରତିବନ୍ଧିତ ବକେଟରେ ରଖାଯାଇଛି"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"ବାର୍ତ୍ତାଳାପ"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ଗୋଷ୍ଠୀ ବାର୍ତ୍ତାଳାପ"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index d2ae05212956..893719eafd50 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string> <string name="factory_reset_message" msgid="2657049595153992213">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਵਰਤੀ ਨਹੀਂ ਜਾ ਸਕਦੀ। ਹੁਣ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।\n\nਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਵਾਲ ਹਨ, ਤਾਂ ਆਪਣੀ ਸੰਸਥਾ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਿੰਟ ਕਰਨਾ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ਆਪਣੀਆਂ ਨਿੱਜੀ ਐਪਾਂ ਅਣਬਲਾਕ ਕਰੋ"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ਐਪਾਂ ਕੱਲ੍ਹ ਬਲਾਕ ਹੋ ਜਾਣਗੀਆਂ"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"ਤੁਹਾਡਾ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੂੰ <xliff:g id="DAYS">%1$d</xliff:g> ਦਿਨਾਂ ਤੋਂ ਵੱਧ ਸਮੇਂ ਤੱਕ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦਾ"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"ਆਪਣਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਚਾਲੂ ਕਰੋ"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਆਪਣਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਚਾਲੂ ਨਹੀਂ ਕਰਦੇ ਤੁਹਾਡੀਆਂ ਨਿੱਜੀ ਐਪਾਂ ਬਲਾਕ ਰਹਿੰਦੀਆਂ ਹਨ"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"ਕੱਲ੍ਹ ਨੂੰ ਤੁਹਾਡੀਆਂ ਨਿੱਜੀ ਐਪਾਂ ਬਲਾਕ ਕਰ ਦਿੱਤੀਆਂ ਜਾਣਗੀਆਂ"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਚਾਲੂ ਕਰੋ"</string> <string name="me" msgid="6207584824693813140">"ਮੈਂ"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ਟੈਬਲੈੱਟ ਵਿਕਲਪ"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ਕੁਝ ਸਕਿੰਟਾਂ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਨੂੰ ਦਬਾਈ ਰੱਖਣਾ <xliff:g id="SERVICE">%1$s</xliff:g>, ਇੱਕ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਚਾਲੂ ਕਰ ਦਿੰਦਾ ਹੈ। ਇਹ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਕੰਮ ਕਰਨ ਦੇ ਤਰੀਕੇ ਨੂੰ ਬਦਲ ਸਕਦਾ ਹੈ।\n\nਸੈਟਿੰਗਾਂ ਅਤੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿੱਚ ਤੁਸੀਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਕਿਸੇ ਹੋਰ ਵਿਸ਼ੇਸ਼ਤਾ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ।"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ਚਾਲੂ ਕਰੋ"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ਚਾਲੂ ਨਾ ਕਰੋ"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ਚਾਲੂ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ਬੰਦ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ਕੀ <xliff:g id="SERVICE">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪੂਰਾ ਕੰਟਰੋਲ ਦੇਣਾ ਹੈ?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"ਜੇਕਰ ਤੁਸੀਂ <xliff:g id="SERVICE">%1$s</xliff:g> ਚਾਲੂ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਇਨਕ੍ਰਿਪਸ਼ਨ ਦਾ ਵਿਸਤਾਰ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰੇਗਾ।"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ਪੂਰਾ ਕੰਟਰੋਲ ਉਹਨਾਂ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਹੈ ਜੋ ਪਹੁੰਚਯੋਗਤਾ ਸੰਬੰਧੀ ਲੋੜਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਦੀਆਂ ਹਨ, ਪਰ ਜ਼ਿਆਦਾਤਰ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਨਹੀਂ ਹੁੰਦਾ।"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ਠੀਕ ਹੈ"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"ਬੈਟਰੀ ਲਾਈਫ਼ ਵਧਾਉਣ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ:\n ਗੂੜ੍ਹਾ ਥੀਮ ਚਾਲੂ ਕਰਦਾ ਹੈ\n ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ, ਕੁਝ ਦ੍ਰਿਸ਼ਟੀਗਤ ਪ੍ਰਭਾਵਾਂ, ਅਤੇ \"Ok Google\" ਵਰਗੀਆਂ ਹੋਰ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਬੰਦ ਕਰਦਾ ਹੈ ਜਾਂ ਉਹਨਾਂ \'ਤੇ ਪਾਬੰਦੀ ਲਗਾਉਂਦਾ ਹੈ\n\n"<annotation id="url">"ਹੋਰ ਜਾਣੋ"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"ਬੈਟਰੀ ਲਾਈਫ਼ ਵਧਾਉਣ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ:\n ਗੂੜ੍ਹਾ ਥੀਮ ਚਾਲੂ ਕਰਦਾ ਹੈ\n ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ, ਕੁਝ ਦ੍ਰਿਸ਼ ਪ੍ਰਭਾਵਾਂ, ਅਤੇ \"Ok Google\" ਵਰਗੀਆਂ ਹੋਰ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਬੰਦ ਕਰਦਾ ਹੈ ਜਾਂ ਉਹਨਾਂ \'ਤੇ ਪਾਬੰਦੀ ਲਗਾਉਂਦਾ ਹੈ"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ਡਾਟਾ ਵਰਤੋਂ ਘਟਾਉਣ ਵਿੱਚ ਮਦਦ ਲਈ, ਡਾਟਾ ਸੇਵਰ ਕੁਝ ਐਪਾਂ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਟਾ ਭੇਜਣ ਜਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਤੋਂ ਰੋਕਦਾ ਹੈ। ਤੁਹਾਡੇ ਵੱਲੋਂ ਵਰਤਮਾਨ ਤੌਰ \'ਤੇ ਵਰਤੀ ਜਾ ਰਹੀ ਐਪ ਡਾਟਾ \'ਤੇ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਉਹ ਇੰਝ ਕਦੇ-ਕਦਾਈਂ ਕਰ ਸਕਦੀ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸ ਦਾ ਮਤਲਬ ਇਹ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਚਿੱਤਰ ਤਦ ਤੱਕ ਨਹੀਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕੀਤੇ ਜਾਂਦੇ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ \'ਤੇ ਟੈਪ ਨਹੀਂ ਕਰਦੇ।"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ਕੀ ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਕਰਨਾ ਹੈ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ਚਾਲੂ ਕਰੋ"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ਸੂਚਨਾਵਾਂ"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ਪਾਵਰ ਵਿੰਡੋ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ਲਾਕ ਸਕ੍ਰੀਨ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ਪਹੁੰਚਯੋਗਤਾ ਮੀਨੂ"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਦੀ ਸੁਰਖੀ ਪੱਟੀ।"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ਨੂੰ ਪ੍ਰਤਿਬੰਧਿਤ ਖਾਨੇ ਵਿੱਚ ਪਾਇਆ ਗਿਆ ਹੈ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"ਗੱਲਬਾਤ"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"ਗੁਰੱਪ ਗੱਲਬਾਤ"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index f219bd3ac143..eee3dc6760f6 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -204,9 +204,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Twoje urządzenie zostanie wyczyszczone"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Nie można użyć aplikacji administratora. Dane z urządzenia zostaną wykasowane.\n\nJeśli masz pytania, skontaktuj się z administratorem organizacji."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Drukowanie wyłączone przez: <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Odblokuj aplikacje osobiste"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Blokada aplikacji – jutro"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Administrator IT nie pozwala na wstrzymanie profilu do pracy na dłużej niż <xliff:g id="DAYS">%1$d</xliff:g> dni"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Włącz profil do pracy"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Zablokowano aplikacje osobiste do czasu włączenia profilu do pracy"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Twoje aplikacje osobiste zostaną zablokowane jutro"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Włącz profil do pracy"</string> <string name="me" msgid="6207584824693813140">"Ja"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcje tabletu"</string> @@ -1675,6 +1675,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Przytrzymanie obu klawiszy głośności przez kilka sekund włącza usługę <xliff:g id="SERVICE">%1$s</xliff:g>, stanowiącą ułatwienie dostępu. Może to zmienić sposób działania urządzenia.\n\nAby zmienić ten skrót i wskazać inną funkcję, kliknij Ustawienia > Ułatwienia dostępu."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Włącz"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nie włączaj"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"WŁ."</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"WYŁ."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Pozwolić usłudze <xliff:g id="SERVICE">%1$s</xliff:g> na pełną kontrolę nad urządzeniem?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jeśli włączysz usługę <xliff:g id="SERVICE">%1$s</xliff:g>, Twoje urządzenie nie będzie korzystać z blokady ekranu, by usprawnić szyfrowanie danych."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Pełna kontrola jest odpowiednia dla aplikacji, które pomagają Ci radzić sobie z niepełnosprawnością, ale nie należy jej przyznawać wszystkim aplikacjom."</string> @@ -1838,8 +1840,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Zaktualizowany przez administratora"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Usunięty przez administratora"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Aby wydłużyć czas pracy na baterii, Oszczędzanie baterii:\n włącza tryb ciemny, \nwyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne oraz inne funkcje, np. „OK Google”.\n\n"<annotation id="url">"Więcej informacji"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Aby wydłużyć czas pracy na baterii, Oszczędzanie baterii:\n· włącza tryb ciemny,\n· wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne oraz inne funkcje, np. „OK Google”."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Oszczędzanie danych uniemożliwia niektórym aplikacjom wysyłanie i odbieranie danych w tle, zmniejszając w ten sposób ich użycie. Aplikacja, z której w tej chwili korzystasz, może uzyskiwać dostęp do danych, ale rzadziej. Może to powodować, że obrazy będą się wyświetlać dopiero po kliknięciu."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Włączyć Oszczędzanie danych?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Włącz"</string> @@ -2106,13 +2110,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Powiadomienia"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Szybkie ustawienia"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Okno opcji zasilania"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Przełącz podzielony ekran"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekran blokady"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Zrzut ekranu"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu ułatwień dostępu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Pasek napisów w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Umieszczono pakiet <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> w zasobniku danych RESTRICTED"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Rozmowa"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Rozmowa grupowa"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 624560ec822c..8c37b5e30d4f 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível usar o aplicativo para administrador. Seu dispositivo passará por uma limpeza agora.\n\nEm caso de dúvidas, entre em contato com o administrador da sua organização."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desbloquear apps pessoais"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Os apps serão bloq. amanhã"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Seu administrador de TI não permite que o perfil de trabalho seja pausado por mais de <xliff:g id="DAYS">%1$d</xliff:g> dias"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Ativar perfil de trabalho"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Seus apps pessoais ficarão bloqueados até você ativar o perfil de trabalho"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Seus apps pessoais serão bloqueados amanhã"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Ativar perfil de trabalho"</string> <string name="me" msgid="6207584824693813140">"Eu"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opções do tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Manter as duas teclas de volume pressionadas por alguns segundos ativa o serviço <xliff:g id="SERVICE">%1$s</xliff:g>, um recurso de acessibilidade. Isso pode mudar a forma como seu dispositivo funciona.\n\nÉ possível trocar o uso desse atalho para outro recurso em \"Config. > Acessibilidade\"."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ativar"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Não ativar"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ATIVADO"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESATIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permitir que o <xliff:g id="SERVICE">%1$s</xliff:g> tenha controle total do seu dispositivo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se o <xliff:g id="SERVICE">%1$s</xliff:g> for ativado, o dispositivo não usará o bloqueio de tela para melhorar a criptografia de dados."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controle total é adequado para apps que ajudam você com as necessidades de acessibilidade, mas não para a maioria dos apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Para aumentar a duração da bateria, a \"Economia de bateria: \n ativa o tema escuro;\n·desativa ou restringe atividades em segundo plano, alguns efeitos visuais e outros recursos, como o \"Ok Google\".\n\n"<annotation id="url">"Saiba mais"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Para aumentar a duração da carga, a \"Economia de bateria\": \n·ativa o tema escuro;\n·desativa ou restringe atividades em segundo plano, alguns efeitos visuais e outros recursos, como o \"Ok Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não sejam exibidas até que você toque nelas."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Ativar Economia de dados?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string> @@ -2038,16 +2042,20 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificações"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Configurações rápidas"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Caixa de diálogo de liga/desliga"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ativar tela dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloquear tela"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capturar tela"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu de acessibilidade"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas do app <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversa"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversa em grupo"</string> - <string name="unread_convo_overflow" msgid="920517615597353833">"+ de <xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> + <string name="unread_convo_overflow" msgid="920517615597353833">"+ <xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> <string name="resolver_personal_tab" msgid="2051260504014442073">"Pessoal"</string> <string name="resolver_work_tab" msgid="2690019516263167035">"Trabalho"</string> <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Visualização pessoal"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index b0ab7264ec7c..a1c8f6be285d 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"O seu dispositivo será apagado"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível utilizar a aplicação de administrador. O seu dispositivo será agora apagado.\n\nSe tiver questões, contacte o administrador da entidade."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desbloqueie as apps pessoais"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"As apps são bloqueadas amanhã"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"O seu administrador de TI não permite que o seu perfil de trabalho seja colocado em pausa durante mais de <xliff:g id="DAYS">%1$d</xliff:g> dias."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Ative o perfil de trabalho"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"As suas apps pessoais estão bloqueadas até ativar o seu perfil de trabalho."</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"As suas apps pessoais serão bloqueadas amanhã."</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Ativar perfil de trabalho"</string> <string name="me" msgid="6207584824693813140">"Eu"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opções do tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Manter premidas ambas as teclas de volume durante alguns segundos ativa o serviço <xliff:g id="SERVICE">%1$s</xliff:g>, uma funcionalidade de acessibilidade. Esta pode alterar a forma como o seu dispositivo funciona.\n\nPode alterar este atalho para outra funcionalidade em Definições > Acessibilidade."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ativar"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Não ativar"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ATIVADO"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESATIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permitir que o serviço <xliff:g id="SERVICE">%1$s</xliff:g> tenha controlo total sobre o seu dispositivo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se ativar o serviço <xliff:g id="SERVICE">%1$s</xliff:g>, o dispositivo não utilizará o bloqueio de ecrã para otimizar a encriptação de dados."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controlo total é adequado para aplicações que ajudam nas necessidades de acessibilidade, mas não para a maioria das aplicações."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu gestor"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado pelo seu gestor"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Para prolongar a autonomia da bateria, a Poupança de bateria:\n·Ativa o tema escuro.\n·Desativa ou restringe a atividade em segundo plano, alguns efeitos visuais e outras funcionalidades como \"Ok Google\".\n\n"<annotation id="url">"Saber mais"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Para prolongar a autonomia da bateria, a Poupança de bateria:\n·Ativa o tema escuro.\n·Desativa ou restringe a atividade em segundo plano, alguns efeitos visuais e outras funcionalidades como \"Ok Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir a utilização de dados, a Poupança de dados impede que algumas aplicações enviem ou recebam dados em segundo plano. Uma determinada aplicação que esteja a utilizar atualmente pode aceder aos dados, mas é possível que o faça com menos frequência. Isto pode significar, por exemplo, que as imagens não são apresentadas até que toque nas mesmas."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Pretende ativar a Poupança de dados?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificações"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Definições rápidas"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Caixa de diálogo de energia"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ativar/desativar o ecrã dividido"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ecrã de bloqueio"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de ecrã"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu Acessibilidade"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas da aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no contentor RESTRITO."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversa"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversa de grupo"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"> <xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 624560ec822c..8c37b5e30d4f 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível usar o aplicativo para administrador. Seu dispositivo passará por uma limpeza agora.\n\nEm caso de dúvidas, entre em contato com o administrador da sua organização."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Desbloquear apps pessoais"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Os apps serão bloq. amanhã"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Seu administrador de TI não permite que o perfil de trabalho seja pausado por mais de <xliff:g id="DAYS">%1$d</xliff:g> dias"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Ativar perfil de trabalho"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Seus apps pessoais ficarão bloqueados até você ativar o perfil de trabalho"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Seus apps pessoais serão bloqueados amanhã"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Ativar perfil de trabalho"</string> <string name="me" msgid="6207584824693813140">"Eu"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opções do tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Manter as duas teclas de volume pressionadas por alguns segundos ativa o serviço <xliff:g id="SERVICE">%1$s</xliff:g>, um recurso de acessibilidade. Isso pode mudar a forma como seu dispositivo funciona.\n\nÉ possível trocar o uso desse atalho para outro recurso em \"Config. > Acessibilidade\"."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ativar"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Não ativar"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ATIVADO"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESATIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permitir que o <xliff:g id="SERVICE">%1$s</xliff:g> tenha controle total do seu dispositivo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se o <xliff:g id="SERVICE">%1$s</xliff:g> for ativado, o dispositivo não usará o bloqueio de tela para melhorar a criptografia de dados."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controle total é adequado para apps que ajudam você com as necessidades de acessibilidade, mas não para a maioria dos apps."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Para aumentar a duração da bateria, a \"Economia de bateria: \n ativa o tema escuro;\n·desativa ou restringe atividades em segundo plano, alguns efeitos visuais e outros recursos, como o \"Ok Google\".\n\n"<annotation id="url">"Saiba mais"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Para aumentar a duração da carga, a \"Economia de bateria\": \n·ativa o tema escuro;\n·desativa ou restringe atividades em segundo plano, alguns efeitos visuais e outros recursos, como o \"Ok Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não sejam exibidas até que você toque nelas."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Ativar Economia de dados?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string> @@ -2038,16 +2042,20 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificações"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Configurações rápidas"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Caixa de diálogo de liga/desliga"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ativar tela dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloquear tela"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capturar tela"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu de acessibilidade"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas do app <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversa"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversa em grupo"</string> - <string name="unread_convo_overflow" msgid="920517615597353833">"+ de <xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> + <string name="unread_convo_overflow" msgid="920517615597353833">"+ <xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> <string name="resolver_personal_tab" msgid="2051260504014442073">"Pessoal"</string> <string name="resolver_work_tab" msgid="2690019516263167035">"Trabalho"</string> <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Visualização pessoal"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 73c3e42696dc..0f95eccfa572 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -202,9 +202,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Datele de pe dispozitiv vor fi șterse"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Aplicația de administrare nu poate fi utilizată. Dispozitivul va fi șters.\n\nDacă aveți întrebări, contactați administratorul organizației dvs."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Printare dezactivată de <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Deblocați aplicațiile personale"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Aplicațiile vor fi blocate mâine"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Administratorul IT nu permite ca profilul de serviciu să fie întrerupt mai mult de <xliff:g id="DAYS">%1$d</xliff:g> zile"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activați profilul de serviciu"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Aplicațiile personale sunt blocate până când activați profilul de serviciu"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Aplicațiile personale vor fi blocate mâine"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Activați profilul de serviciu"</string> <string name="me" msgid="6207584824693813140">"Eu"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opțiuni tablet PC"</string> @@ -1653,6 +1653,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Dacă apăsați ambele taste de volum câteva secunde, activați funcția de accesibilitate <xliff:g id="SERVICE">%1$s</xliff:g>. Acest lucru poate schimba funcționarea dispozitivului.\n\nPuteți alege altă funcție pentru această comandă în Setări > Accesibilitate."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activați"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nu activați"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVAT"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DEZACTIVAT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permiteți serviciului <xliff:g id="SERVICE">%1$s</xliff:g> să aibă control total asupra dispozitivului dvs.?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Dacă activați <xliff:g id="SERVICE">%1$s</xliff:g>, dispozitivul nu va folosi blocarea ecranului pentru a îmbunătăți criptarea datelor."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Controlul total este adecvat pentru aplicații care vă ajută cu accesibilitatea, însă nu pentru majoritatea aplicaților."</string> @@ -1815,8 +1817,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizat de administratorul dvs."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Șters de administratorul dvs."</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Pentru a prelungi autonomia bateriei, Economisirea bateriei:\n·activează tema întunecată;\n·activează sau restricționează activitatea în fundal, unele efecte vizuale și alte funcții, cum ar fi „Ok Google”.\n\n"<annotation id="url">"Aflați mai multe"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Pentru a prelungi autonomia bateriei, Economisirea bateriei:\n·activează tema întunecată;\n·activează sau restricționează activitatea în fundal, unele efecte vizuale și alte funcții, cum ar fi „Ok Google”."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Pentru a contribui la reducerea utilizării de date, Economizorul de date împiedică unele aplicații să trimită sau să primească date în fundal. O aplicație pe care o folosiți poate accesa datele, însă mai rar. Aceasta poate însemna, de exemplu, că imaginile se afișează numai după ce le atingeți."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Activați Economizorul de date?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activați"</string> @@ -2072,13 +2076,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notificări"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Setări rapide"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Power Dialog"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activați ecranul împărțit"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ecran de blocare"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captură de ecran"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Meniul Accesibilitate"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Bară cu legenda pentru <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a fost adăugat la grupul RESTRICȚIONATE"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversație"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Conversație de grup"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index a6d8f2504d5a..c2e35eb4c033 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -204,9 +204,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Все данные с устройства будут удалены"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Невозможно использовать приложение для администрирования. С устройства будут удалены все данные.\n\nЕсли у вас возникли вопросы, обратитесь к администратору."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Функция печати отключена приложением \"<xliff:g id="OWNER_APP">%s</xliff:g>\""</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Разблокируйте личные приложения"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Завтра приложения будут заблокированы"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Системный администратор запретил отключать рабочий профиль более чем на <xliff:g id="DAYS">%1$d</xliff:g> дн."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Включите рабочий профиль"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Личные приложения будут заблокированы, пока вы не включите рабочий профиль."</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Личные приложения будут заблокированы завтра."</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Включить рабочий профиль"</string> <string name="me" msgid="6207584824693813140">"Я"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Настройки планшетного ПК"</string> @@ -1675,6 +1675,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Чтобы включить функцию \"<xliff:g id="SERVICE">%1$s</xliff:g>\", нажмите обе кнопки регулировки громкости на несколько секунд. Обратите внимание, что в работе устройства могут произойти изменения.\n\nЧтобы назначить это сочетание клавиш другой функции, перейдите в настройки и выберите \"Специальные возможности\"."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Включить"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Не включать"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"Включено"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"Выключено"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Предоставить сервису \"<xliff:g id="SERVICE">%1$s</xliff:g>\" полный контроль над устройством?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Если включить сервис \"<xliff:g id="SERVICE">%1$s</xliff:g>\", устройство не будет использовать блокировку экрана для защиты данных."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Полный контроль нужен приложениям для реализации специальных возможностей и не нужен большинству остальных."</string> @@ -1838,8 +1840,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Обновлено администратором"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Удалено администратором"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Чтобы продлить время работы от батареи, в режиме энергосбережения:\nвключается тёмная тема;\nотключаются или ограничиваются фоновые процессы, некоторые визуальные эффекты и другие функции (например, распознавание команды \"Окей, Google\").\n\n"<annotation id="url">"Подробнее…"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Чтобы продлить время работы от батареи, в режиме энергосбережения:\nвключается тёмная тема;\nотключаются или ограничиваются фоновые процессы, некоторые визуальные эффекты и другие функции (например, распознавание команды \"Окей, Google\")."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"В режиме экономии трафика фоновая передача данных для некоторых приложений отключена. Приложение, которым вы пользуетесь, может получать и отправлять данные, но реже, чем обычно. Например, изображения могут не загружаться, пока вы не нажмете на них."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Включить экономию трафика?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Включить"</string> @@ -2106,13 +2110,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Уведомления"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Быстрые настройки"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Диалоговое окно питания"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Включить или выключить разделение экрана"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заблокированный экран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Меню специальных возможностей"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Строка субтитров в приложении \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Приложение \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" помещено в категорию с ограниченным доступом."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Чат"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групповой чат"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 3a8639e1e2f1..03ef434c4ed3 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"ඔබගේ උපාංගය මකා දැමෙනු ඇත"</string> <string name="factory_reset_message" msgid="2657049595153992213">"පරිපාලක යෙදුම භාවිතා කළ නොහැකිය. ඔබේ උපාංගය දැන් මකා දමනු ඇත.\n\nඔබට ප්රශ්න තිබේ නම්, ඔබේ සංවිධානයේ පරිපාලකට අමතන්න."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> විසින් මුද්රණය කිරීම අබල කර ඇත."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"ඔබේ පෞද්ගලික යෙදුම් අනවහිර කර"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"හෙට යෙදුම් අවහිර කරනු ඇත"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"ඔබේ IT පරිපාලක ඔබේ කාර්යාල පැතිකඩ දින <xliff:g id="DAYS">%1$d</xliff:g>කට වඩා විරාම කිරීමට ඉඩ නොදේ"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"ඔබේ කාර්යාල පැතිකඩ ඔන් කරන්න"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"ඔබ ඔබගේ කාර්යාල පැතිකඩ ක්රියාත්මක කරන තෙක් ඔබගේ පෞද්ගලික යෙදුම් අවහිර කර ඇත"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"ඔබේ පෞද්ගලික යෙදුම් හෙට අවහිර කරනු ඇත"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"කාර්යාල පැතිකඩ ක්රියාත්මක කරන්න"</string> <string name="me" msgid="6207584824693813140">"මම"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ටැබ්ලට විකල්ප"</string> @@ -1633,6 +1633,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"හඬ පරිමා යතුරු දෙකම තත්පර කීපයකට පහළට අල්ලාගෙන සිටීම ප්රවේශ්යතා විශේෂාංගයක් වන <xliff:g id="SERVICE">%1$s</xliff:g> ක්රියාත්මක කරයි. මෙය ඔබේ උපාංගය ක්රියා කරන ආකාරය වෙනස් කළ හැකිය.\n\nඔබට මෙම කෙටිමග සැකසීම් > ප්රවේශ්යතාව හි තවත් විශේෂාංගයකට වෙනස් කළ හැකිය."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ක්රියාත්මක කරන්න"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ක්රියාත්මක නොකරන්න"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"සක්රියයි"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"අක්රියයි"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> හට ඔබේ උපාංගයේ සම්පූර්ණ පාලනය තබා ගැනීමට ඉඩ දෙන්නද?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"ඔබ <xliff:g id="SERVICE">%1$s</xliff:g> ක්රියාත්මක කරන්නේ නම්, දත්ත සංකේතනය වැඩිදියුණු කිරීමට ඔබේ උපාංගය ඔබේ තිර අගුල භාවිත නොකරනු ඇත."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"පූර්ණ පාලනය ඔබට ප්රවේශ්යතා අවශ්යතා සමඟ උදවු කරන යෙදුම් සඳහා සුදුසු වන නමුත් බොහෝ යෙදුම් සඳහා සුදුසු නොවේ."</string> @@ -1794,8 +1796,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"ඔබගේ පරිපාලක මඟින් යාවත්කාලීන කර ඇත"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ඔබගේ පරිපාලක මඟින් මකා දමා ඇත"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"හරි"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"බැටරියේ ජීව කාලය දික් කිරීමට, බැටරි සුරැකුම:\n·අඳුරු තේමාව ක්රියාත්මක කරයි\n·පසුබිමේ ක්රියාකාරකම, සමහර දෘෂ්ය ප්රයෝග සහ “Hey Google” වැනි වෙනත් විශේෂාංග ක්රියාවිරහිත කරයි නැතහොත් අවහිර කරයි\n\n"<annotation id="url">"තව දැන ගන්න"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"බැටරියේ ජීව කාලය දික් කිරීමට, බැටරි සුරැකුම:\n·අඳුරු තේමාව ක්රියාත්මක කරයි\n·පසුබිමේ ක්රියාකාරකම, සමහර දෘෂ්ය ප්රයෝග සහ “Hey Google” වැනි වෙනත් විශේෂාංග ක්රියාවිරහිත කරයි නැතහොත් අවහිර කරයි"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"දත්ත භාවිතය අඩු කිරීමට උදවු වීමට, දත්ත සුරැකුම සමහර යෙදුම් පසුබිමින් දත්ත යැවීම සහ ලබා ගැනීම වළක්වයි. ඔබ දැනට භාවිත කරන යෙදුමකට දත්ත වෙත පිවිසීමට හැකිය, නමුත් එසේ කරන්නේ කලාතුරකින් විය හැකිය. මෙයින් අදහස් වන්නේ, උදාහරණයක් ලෙස, එම රූප ඔබ ඒවාට තට්ටු කරන තෙක් සංදර්ශනය නොවන බවය."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"දත්ත සුරැකුම ක්රියාත්මක කරන්නද?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ක්රියාත්මක කරන්න"</string> @@ -2040,13 +2044,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"දැනුම්දීම්"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ඉක්මන් සැකසීම්"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"බල සංවාදය"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"බෙදුම් තිරය ටොගල කරන්න"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"අගුලු තිරය"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"තිර රුව"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ප්රවේශ්යතා මෙනුව"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> හි සිරස්තල තීරුව."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> අවහිර කළ බාල්දියට දමා ඇත"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"සංවාදය"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"සමූහ සංවාදය"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index dee51d552503..bee9e726f8fa 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -204,9 +204,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Vaše zariadenie bude vymazané"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Daná aplikácia na správu sa nedá použiť. Vaše zariadenie bude vymazané.\n\nV prípade otázok kontaktujte správcu organizácie."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Tlač zakázala aplikácia <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Odblokujte osobné aplikácie"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Aplikácie sa zajtra zablokujú"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Správca IT vám zakázal pozastaviť pracovný profil na viac ako <xliff:g id="DAYS">%1$d</xliff:g> d."</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Zapnúť pracovný profil"</string> <string name="me" msgid="6207584824693813140">"Ja"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Možnosti tabletu"</string> @@ -1675,6 +1678,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Pridržaním oboch klávesov hlasitosti na niekoľko sekúnd zapnete funkciu dostupnosti <xliff:g id="SERVICE">%1$s</xliff:g>. Môže sa tým zmeniť spôsob fungovania vášho zariadenia.\n\nTúto skratku môžete zmeniť na inú funkciu v časti Nastavenia > Dostupnosť."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Zapnúť"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nezapínať"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ZAP."</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VYP."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Chcete povoliť službe <xliff:g id="SERVICE">%1$s</xliff:g> úplnú kontrolu nad zariadením?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ak zapnete službu <xliff:g id="SERVICE">%1$s</xliff:g>, vaše zariadenie nezvýši úroveň šifrovania údajov zámkou obrazovky."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Úplná kontrola je vhodná pre aplikácie, ktoré vám pomáhajú s dostupnosťou, ale nie pre väčšinu aplikácií."</string> @@ -1838,8 +1843,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizoval správca"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Odstránil správca"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Šetrič batérie predlžuje výdrž batérie:\n·zapnutím tmavého motívu;\n·vypnutím alebo obmedzením aktivity na pozadí, niektorých vizuálnych efektov a ďalších funkcií, ako napríklad „Hey Google“.\n\n"<annotation id="url">"Ďalšie informácie"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Šetrič batérie predlžuje výdrž batérie:\n·zapnutím tmavého motívu;\n·vypnutím alebo obmedzením aktivity na pozadí, niektorých vizuálnych efektov a ďalších funkcií, ako napríklad „Hey Google“."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"S cieľom znížiť spotrebu dát bráni šetrič dát niektorým aplikáciám odosielať alebo prijímať dáta na pozadí. Aplikácia, ktorú práve používate, môže využívať dáta, ale možno to bude robiť menej často. Znamená to napríklad, že sa nezobrazia obrázky, kým na ne neklepnete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Chcete zapnúť šetrič dát?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Zapnúť"</string> @@ -2106,13 +2113,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Upozornenia"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Rýchle nastavenia"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialógové okno napájania"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Prepnúť rozdelenú obrazovku"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Uzamknúť obrazovku"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snímka obrazovky"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Ponuka Dostupnosť"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Popis aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balík <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> bol vložený do kontajnera OBMEDZENÉ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Konverzácia"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Skupinová konverzácia"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 3ac05cf352ea..b22cb17fe1f5 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -204,9 +204,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Podatki v napravi bodo izbrisani"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Skrbniške aplikacije ni mogoče uporabljati. Podatki v napravi bodo izbrisani.\n\nČe imate vprašanja, se obrnite na skrbnika organizacije."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Tiskanje je onemogočil pravilnik <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Odblokirajte oseb. aplikacije"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Jutri bodo aplikac. blokirane"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Skrbnik za IT ne dovoli, da bi bil delovni profil začasno zaustavljen dlje kot <xliff:g id="DAYS">%1$d</xliff:g> dni"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Vklopi delovni profil"</string> <string name="me" msgid="6207584824693813140">"Jaz"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Možnosti tabličnega računalnika"</string> @@ -1675,6 +1678,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Če za nekaj sekund pridržite obe tipki za glasnost, boste vklopili storitev <xliff:g id="SERVICE">%1$s</xliff:g>, ki je funkcija za ljudi s posebnimi potrebami. To lahko spremeni način delovanja naprave.\n\nTo bližnjico lahko v meniju »Nastavitve« > »Funkcije za ljudi s posebnimi potrebami« spremenite, da bo uporabljena za drugo funkcijo."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Vklopi"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ne vklopi"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"VKLOPLJENO"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IZKLOPLJ."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Ali storitvi <xliff:g id="SERVICE">%1$s</xliff:g> dovolite popoln nadzor nad svojo napravo?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Če vklopite storitev <xliff:g id="SERVICE">%1$s</xliff:g>, vaša naprava ne bo uporabljala zaklepanja zaslona za izboljšanje šifriranja podatkov."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Popoln nadzor je ustrezen za aplikacije, ki vam pomagajo pri funkcijah za ljudi s posebnimi potrebami, vendar ne za večino aplikacij."</string> @@ -1838,8 +1843,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Posodobil skrbnik"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisal skrbnik"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"V redu"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Funkcija varčevanja z energijo baterije tako podaljša čas delovanja baterije:\n·Vklopi temno temo,\n·izklopi ali omeji izvajanje dejavnosti v ozadju, nekaterih vizualnih učinkov in drugih funkcij, kot je »Hey Google«.\n\n"<annotation id="url">"Več o tem"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Funkcija varčevanja z energijo baterije podaljša čas delovanja baterije tako:\n·vklopi temno temo,\n·izklopi ali omeji izvajanje dejavnosti v ozadju, nekaterih vizualnih učinkov in drugih funkcij, kot je »Hey Google«."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Zaradi zmanjševanja prenesene količine podatkov funkcija varčevanja s podatki nekaterim aplikacijam preprečuje, da bi v ozadju pošiljale ali prejemale podatke. Aplikacija, ki jo trenutno uporabljate, lahko prenaša podatke, vendar to morda počne manj pogosto. To na primer pomeni, da se slike ne prikažejo, dokler se jih ne dotaknete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Vklop varčevanja s podatki?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Vklop"</string> @@ -2106,13 +2113,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obvestila"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Hitre nastavitve"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Pogovorno okno o porabi energije"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Preklop razdeljenega zaslona"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaklenjen zaslon"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Posnetek zaslona"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Meni s funkcijami za ljudi s posebnimi potrebami"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Vrstica s podnapisi aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je bil dodan v segment OMEJENO"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Pogovor"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Skupinski pogovor"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 6bf4306ed2d3..10cb62da4215 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Pajisja do të spastrohet"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Aplikacioni i administratorit nuk mund të përdoret. Pajisja jote tani do të fshihet.\n\nNëse ke pyetje, kontakto me administratorin e organizatës."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Printimi është çaktivizuar nga <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Zhblloko aplikacionet e tua personale"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Aplikacionet do të bllokohen nesër"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Administratori yt i teknologjisë së informacionit nuk e lejon profilin tënd të punës të vendoset në pauzë për më shumë se <xliff:g id="DAYS">%1$d</xliff:g> ditë"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Aktivizo profilin e punës"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Aplikacionet e tua personale janë bllokuar derisa të aktivizosh profilin tënd të punës"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Aplikacionet e tua personale do të bllokohen nesër"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Aktivizo profilin e punës"</string> <string name="me" msgid="6207584824693813140">"Unë"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opsionet e tabletit"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Mbajtja shtypur e dy tasteve të volumit për pak sekonda aktivizon <xliff:g id="SERVICE">%1$s</xliff:g>, një veçori të qasshmërisë. Kjo mund të ndryshojë mënyrën se si funksionon pajisja jote.\n\nMund të ndryshosh këtë shkurtore te një veçori tjetër te Cilësimet > Qasshmëria."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktivizo"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Mos e aktivizo"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIV"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"JOAKTIV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Do të lejosh që <xliff:g id="SERVICE">%1$s</xliff:g> të ketë kontroll të plotë të pajisjes sate?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Nëse aktivizon <xliff:g id="SERVICE">%1$s</xliff:g>, pajisja nuk do të përdorë kyçjen e ekranit për të përmirësuar enkriptimin e të dhënave."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrolli i plotë është i përshtatshëm për aplikacionet që të ndihmojnë me nevojat e qasshmërisë, por jo për shumicën e aplikacioneve."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Përditësuar nga administratori"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Fshirë nga administratori"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Në rregull"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Për të rritur kohëzgjatjen e baterisë, \"Kursyesi i baterisë\":\n·Aktivizon \"Temën e errët\"\n·Çaktivizon ose kufizon aktivitetin në sfond, disa efekte vizuale dhe veçori të tjera si “Ok Google”\n\n"<annotation id="url">"Mëso më shumë"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Për të rritur kohëzgjatjen e baterisë, \"Kursyesi i baterisë\":\n·Aktivizon \"Temën e errët\"\n·Çaktivizon ose kufizon aktivitetin në sfond, disa efekte vizuale dhe veçori të tjera si “Ok Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Për të ndihmuar në reduktimin e përdorimit të të dhënave, \"Kursyesi i të dhënave\" pengon që disa aplikacione të dërgojnë apo të marrin të dhëna në sfond. Një aplikacion që po përdor aktualisht mund të ketë qasje te të dhënat, por këtë mund ta bëjë më rrallë. Kjo mund të nënkuptojë, për shembull, se imazhet nuk shfaqen kur troket mbi to."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Të aktivizohet \"Kursyesi i të dhënave\"?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivizo"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Njoftimet"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Cilësimet e shpejta"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialogu i energjisë"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Kalo tek ekrani i ndarë"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekrani i kyçjes"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Pamja e ekranit"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menyja e qasshmërisë"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Shiriti i nëntitullit të <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> është vendosur në grupin E KUFIZUAR"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Biseda"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Bisedë në grup"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index e1e62b5c0656..67e1ff4fb148 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -202,9 +202,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Уређај ће бити обрисан"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Не можете да користите ову апликацију за администраторе. Уређај ће сада бити обрисан.\n\nАко имате питања, контактирајте администратора организације."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Штампање је онемогућила апликација <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Одблокирајте личне апликације"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Аплик. ће се блокирати сутра"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"ИТ администратор вам не дозвољава да профил за Work паузирате више од <xliff:g id="DAYS">%1$d</xliff:g> дана"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Укључите профил за Work"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Личне апликације су блокиране док не укључите профил за Work"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Личне апликације ће бити блокиране сутра"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Укључи профил за Work"</string> <string name="me" msgid="6207584824693813140">"Ја"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Опције за таблет"</string> @@ -1653,6 +1653,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ако задржите оба тастера за јачину звука пар секунди, укључује се <xliff:g id="SERVICE">%1$s</xliff:g>, функција приступачности. То може да промени начин рада уређаја.\n\nМожете да промените функцију на коју се односи ова пречица у одељку Подешавања > Приступачност."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Укључи"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Не укључуј"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"УКЉУЧЕНО"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИСКЉУЧЕНО"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Желите ли да дозволите да услуга <xliff:g id="SERVICE">%1$s</xliff:g> има потпуну контролу над уређајем?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ако укључите услугу <xliff:g id="SERVICE">%1$s</xliff:g>, уређај неће користити закључавање екрана да би побољшао шифровање података."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Потпуна контрола је примерена за апликације које вам помажу код услуга приступачности, али не и за већину апликација."</string> @@ -1815,8 +1817,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирао је администратор"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Ради дужег трајања батерије, уштеда батерије:\n·укључује тамну тему\n·искључује или ограничава активности у позадини, неке визуелне ефекте и друге функције, на пример, „Ок Google“\n\n"<annotation id="url">"Сазнајте више"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Ради дужег трајања батерије, уштеда батерије:\n·укључује тамну тему\n·искључује или ограничава активности у позадини, неке визуелне ефекте и друге функције, на пример, „Ок Google“"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Да би се смањила потрошња података, Уштеда података спречава неке апликације да шаљу или примају податке у позадини. Апликација коју тренутно користите може да приступа подацима, али ће то чинити ређе. На пример, слике се неће приказивати док их не додирнете."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Желите да укључите Уштеду података?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Укључи"</string> @@ -2072,13 +2076,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Обавештења"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Брза подешавања"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Дијалог напајања"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Укључите/искључите подељени екран"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Закључани екран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Снимак екрана"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Мени Приступачност"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Трака са насловима апликације <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> је додат у сегмент ОГРАНИЧЕНО"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Конверзација"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групна конверзација"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 2e6a848be5cc..840493cf3012 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten kommer att rensas"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Det går inte att använda administratörsappen. Enheten rensas.\n\nKontakta organisationens administratör om du har några frågor."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Utskrift har inaktiverats av <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Återaktivera privata appar"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Appar blockeras i morgon"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT-administratören tillåter inte att din jobbprofil pausas i mer än <xliff:g id="DAYS">%1$d</xliff:g> dagar"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Aktivera jobbprofilen"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Privata appar blockeras tills du aktiverar jobbprofilen"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Dina privata appar blockeras i morgon"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Aktivera jobbprofilen"</string> <string name="me" msgid="6207584824693813140">"Jag"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Alternativ för surfplattan"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Om du trycker ned båda volymknapparna i ett par sekunder aktiveras <xliff:g id="SERVICE">%1$s</xliff:g>, en tillgänglighetsfunktion. Det kan leda till att enheten fungerar annorlunda.\n\nDu kan ändra vilken funktion som ska aktiveras med genvägen under Inställningar > Tillgänglighet."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktivera"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Aktivera inte"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"PÅ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vill du tillåta att <xliff:g id="SERVICE">%1$s</xliff:g> får fullständig kontroll över enheten?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Om du aktiverar <xliff:g id="SERVICE">%1$s</xliff:g> används inte skärmlåset för att förbättra datakryptering på enheten."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Fullständig kontroll lämpar sig för appar med tillgänglighetsfunktioner, men är inte lämplig för de flesta appar."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Administratören uppdaterade paketet"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratören raderade paketet"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Batterisparläget förlänger batteritiden genom att:\n·aktivera mörkt tema\n·inaktivera eller begränsa aktivitet i bakgrunden, vissa visuella effekter och andra funktioner, som ”Hey Google”\n\n"<annotation id="url">"Läs mer"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Batterisparläget förlänger batteritiden genom att:\n·aktivera mörkt tema\n·inaktivera eller begränsa aktivitet i bakgrunden, vissa visuella effekter och andra funktioner, som ”Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Med databesparing kan du minska dataanvändningen genom att hindra en del appar från att skicka eller ta emot data i bakgrunden. Appar som du använder kan komma åt data, men det sker kanske inte lika ofta. Detta innebär t.ex. att bilder inte visas förrän du trycker på dem."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Vill du aktivera Databesparing?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivera"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Aviseringar"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Snabbinställningar"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialogruta för ström"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Aktivera och inaktivera delad skärm"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låsskärm"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skärmdump"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Tillgänglighetsmenyn"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Textningsfält för <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> har placerats i hinken RESTRICTED"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Konversation"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Gruppkonversation"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 355ad13cf0a5..360f41bdfc00 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -200,9 +200,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Data iliyomo kwenye kifaa chako itafutwa"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Huwezi kutumia programu ya msimamizi. Sasa data iliyo kwenye kifaa chako itafutwa.\n\nIkiwa una maswali yoyote, wasiliana na msimamizi wa shirika lako."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Kipengele cha kuchapisha kimezimwa na <xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Acha kuzuia programu za binafsi"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Programu zitazuiwa kesho"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Msimamizi wako wa TEHAMA haruhusu wasifu wako wa kazini kusimamishwa kwa zaidi ya siku <xliff:g id="DAYS">%1$d</xliff:g>"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Washa wasifu wa kazini"</string> <string name="me" msgid="6207584824693813140">"Mimi"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Chaguo za kompyuta ndogo"</string> @@ -1631,6 +1634,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hatua ya kushikilia chini vitufe vyote viwili vya sauti kwa sekunde chache huwasha <xliff:g id="SERVICE">%1$s</xliff:g>, kipengele cha ufikivu. Huenda hatua hii ikabadilisha jinsi kifaa chako kinavyofanya kazi.\n\nUnaweza kubadilisha njia hii ya mkato iwe kipengele kingine katika Mipangilio > Ufikivu."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Washa"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Usiwashe"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"IMEWASHWA"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IMEZIMWA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Ungependa kuruhusu <xliff:g id="SERVICE">%1$s</xliff:g> idhibiti kifaa chako kikamilifu?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ukiwasha <xliff:g id="SERVICE">%1$s</xliff:g>, kifaa chako hakitatumia kipengele cha kufunga skrini yako ili kuboresha usimbaji wa data kwa njia fiche."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Udhibiti kamili unafaa kwa programu zinazokusaidia kwa mahitaji ya ufikivu, ila si kwa programu nyingi."</string> @@ -1792,8 +1797,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Imesasishwa na msimamizi wako"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Imefutwa na msimamizi wako"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Sawa"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Ili kuongeza muda wa matumizi ya betri, Kiokoa Betri:\n.Huwasha Mandhari meusi\n. Huzima au kuzuia shughuli za chinichini, baadhi ya madoido yanayoonekana na vipengele vingine kama vile \"Ok Google\"\n\n"<annotation id="url">"Pata maelezo zaidi"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Ili kuongeza muda wa matumizi ya betri, Kiokoa Betri:\n·Huwasha Mandhari meusi\n·Huzima au kuzuia shughuli za chinichini, baadhi ya madoido yanayoonekana na vipengele vingine kama vile \"Ok Google\""</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Ili kusaidia kupunguza matumizi ya data, Kiokoa Data huzuia baadhi ya programu kupokea na kutuma data chinichini. Programu ambayo unatumia sasa inaweza kufikia data, lakini si kila wakati. Kwa mfano, haitaonyesha picha hadi utakapozifungua."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Ungependa Kuwasha Kiokoa Data?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Washa"</string> @@ -2038,13 +2045,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Arifa"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Mipangilio ya Haraka"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Kidirisha cha Nishati"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Geuza Skrini Iliyogawanywa"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Skrini Iliyofungwa"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Picha ya skrini"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menyu ya Ufikivu"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Upau wa manukuu wa <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> kimewekwa katika kikundi KILICHODHIBITIWA"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Mazungumzo"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Mazungumzo ya Kikundi"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 2a03f365e9d7..c2c9d1615207 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -200,9 +200,12 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"சாதனத் தரவு அழிக்கப்படும்"</string> <string name="factory_reset_message" msgid="2657049595153992213">"நிர்வாகி ஆப்ஸை உபயோகிக்க முடியாது. இப்போது, உங்கள் சாதனம் ஆரம்ப நிலைக்கு மீட்டமைக்கப்படும்.\n\nஏதேனும் கேள்விகள் இருப்பின், உங்கள் நிறுவனத்தின் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"பிரிண்ட் செய்வதை <xliff:g id="OWNER_APP">%s</xliff:g> தடுத்துள்ளது."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"தனிப்பட்ட ஆப்ஸை அனுமதியுங்கள்"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ஆப்ஸ் நாளை தடை செய்யப்படும்"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"பணிக் கணக்கு <xliff:g id="DAYS">%1$d</xliff:g> நாட்களுக்கு மேல் இடைநிறுத்தப்படுவதை உங்கள் IT நிர்வாகி அனுமதிக்கவில்லை"</string> + <!-- no translation found for personal_apps_suspension_title (7561416677884286600) --> + <skip /> + <!-- no translation found for personal_apps_suspension_text (6115455688932935597) --> + <skip /> + <!-- no translation found for personal_apps_suspension_tomorrow_text (6322541302153673994) --> + <skip /> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"பணிக் கணக்கை ஆன் செய்"</string> <string name="me" msgid="6207584824693813140">"நான்"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"டேப்லெட் விருப்பங்கள்"</string> @@ -1631,6 +1634,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"இரண்டு ஒலியளவு விசைகளையும் சில விநாடிகள் பிடித்திருப்பதால் அணுகல்தன்மை அம்சமான <xliff:g id="SERVICE">%1$s</xliff:g> ஆன் ஆகும். இதனால் உங்கள் சாதனம் வேலை செய்யும் முறை மாறக்கூடும்.\n\nஅமைப்புகள் > அணுகல்தன்மைக்குச் சென்று இந்த ஷார்ட்கட்டை வேறு அம்சத்திற்கு மாற்ற முடியும்."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ஆன் செய்"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ஆன் செய்யாதே"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ஆன்"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ஆஃப்"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"உங்கள் சாதனத்தை முழுமையாகக் கட்டுப்படுத்த <xliff:g id="SERVICE">%1$s</xliff:g> சேவையை அனுமதிக்க வேண்டுமா?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> சேவையை ஆன் செய்தால் தரவு என்க்ரிப்ஷனை மேம்படுத்த சாதனம் திரைப் பூட்டைப் பயன்படுத்தாது."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"உங்களுக்கு உதவக்கூடிய ஆப்ஸுக்குக் தேவையான அணுகல்தன்மையை அளித்து முழுக் கட்டுப்பாட்டையும் அளிக்கலாம், ஆனால் பெரும்பாலான ஆப்ஸுக்கு இது பொருந்தாது."</string> @@ -1792,8 +1797,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"உங்கள் நிர்வாகி நீக்கியுள்ளார்"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"சரி"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"பேட்டரி நிலையை நீட்டிப்பதற்காக, பேட்டரி சேமிப்பான்:\n·டார்க் தீமினை ஆன் செய்யும்\n·“Hey Google” போன்ற பிற அம்சங்கள், பின்னணி செயல்பாடுகள், சில விஷுவல் எஃபெக்ட்கள், ஆகியவற்றை ஆஃப் செய்யும் அல்லது கட்டுப்படுத்தும்\n\n"<annotation id="url">"மேலும் அறிக"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"பேட்டரி நிலையை நீட்டிப்பதற்காக, பேட்டரி சேமிப்பான்:\n·டார்க் தீமினை ஆன் செய்யும்\n·“Hey Google” போன்ற பிற அம்சங்கள், பின்னணி செயல்பாடுகள், சில விஷுவல் எஃபெக்ட்கள், ஆகியவற்றை ஆஃப் செய்யும் அல்லது கட்டுப்படுத்தும்"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"டேட்டா உபயோகத்தைக் குறைப்பதற்கு உதவ, பின்புலத்தில் டேட்டாவை அனுப்புவது அல்லது பெறுவதிலிருந்து சில ஆப்ஸை டேட்டா சேமிப்பான் தடுக்கும். தற்போது பயன்படுத்தும் ஆப்ஸானது எப்போதாவது டேட்டாவை அணுகலாம். எடுத்துக்காட்டாக, படங்களை நீங்கள் தட்டும் வரை அவை காட்டப்படாது."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"டேட்டா சேமிப்பானை இயக்கவா?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"இயக்கு"</string> @@ -2038,13 +2045,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"அறிவிப்புகள்"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"விரைவு அமைப்புகள்"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"பவர் உரையாடல்"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"திரைப் பிரிப்பை நிலைமாற்று"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"பூட்டுத் திரை"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ஸ்கிரீன்ஷாட்"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"அணுகல்தன்மை மெனு"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸின் தலைப்புப் பட்டி."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> என்பதை வரம்பிடப்பட்ட பக்கெட்திற்குள் சேர்க்கப்பட்டது"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"உரையாடல்"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"குழு உரையாடல்"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index da5b77cfce6c..b9ef76a27226 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"మీ పరికరంలోని డేటా తొలగించబడుతుంది"</string> <string name="factory_reset_message" msgid="2657049595153992213">"నిర్వాహక యాప్ ఉపయోగించడం సాధ్యపడదు. మీ పరికరంలోని డేటా ఇప్పుడు తొలగించబడుతుంది.\n\nమీకు ప్రశ్నలు ఉంటే, మీ సంస్థ యొక్క నిర్వాహకులను సంప్రదించండి."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"ముద్రణ <xliff:g id="OWNER_APP">%s</xliff:g> ద్వారా నిలిపివేయబడింది."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"మీపర్సనల్యాప్స్నిఅన్బ్లాక్"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"యాప్లు రేపు బ్లాక్ చేయబడతాయి"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"మీ కార్యాలయ ప్రొఫైల్ను <xliff:g id="DAYS">%1$d</xliff:g> రోజుల కంటే ఎక్కువ పాజ్ చేసి ఉంచడానికి మీ IT అడ్మిన్ అనుమతించరు"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"మీ పని ప్రొఫైల్ను ఆన్ చేయి"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"మీరు మీ కార్యాలయ ప్రొఫైల్ను ప్రారంభించే వరకు, మీ వ్యక్తిగత యాప్లు బ్లాక్ చేయబడతాయి"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"మీ వ్యక్తిగత యాప్లు రేపు బ్లాక్ చేయబడతాయి"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"కార్యాలయ ప్రొఫైల్ను ఆన్ చేయండి"</string> <string name="me" msgid="6207584824693813140">"నేను"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"టాబ్లెట్ ఎంపికలు"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"రెండు వాల్యూమ్ కీలను కొన్ని సెకన్ల పాటు నొక్కి పట్టుకోవడం ద్వారా యాక్సెసిబిలిటీ అయిన <xliff:g id="SERVICE">%1$s</xliff:g> ఆన్ అవుతుంది. ఇది మీ పరికరం పని చేసే విధానాన్ని మార్చవచ్చు.\n\nసెట్టింగ్లు > యాక్సెసిబిలిటీలో, వేరొక ఫీచర్ను ప్రారంభించేలా ఈ షార్ట్ కట్ను మీరు మార్చవచ్చు."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ఆన్ చేయి"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ఆన్ చేయకండి"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ఆన్"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ఆఫ్"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>కి మీ పరికరంపై పూర్తి నియంత్రణను ఇవ్వాలనుకుంటున్నారా?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"మీరు <xliff:g id="SERVICE">%1$s</xliff:g>ని ఆన్ చేస్తే, డేటా ఎన్క్రిప్షన్ను మెరుగుపరచడానికి మీ పరికరం మీ స్క్రీన్ లాక్ను ఉపయోగించదు."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"అవసరమైన యాక్సెస్ సామర్ధ్యం కోసం యాప్లకు పూర్తి నియంత్రణ ఇవ్వడం తగిన పనే అయినా, అన్ని యాప్లకు అలా ఇవ్వడం సరికాదు."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"మీ నిర్వాహకులు నవీకరించారు"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"మీ నిర్వాహకులు తొలగించారు"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"సరే"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి, బ్యాటరీ సేవర్ వీటిని చేస్తుంది:\n·ముదురు రంగు థీమ్ను ఆన్ చేస్తుంది\n·బ్యాక్గ్రౌండ్ కార్యకలాపం, కొన్ని విజువల్ ఎఫెక్ట్స్లతో పాటు “Ok Google” వంటి ఇతర ఫీచర్లను ఆపివేస్తుంది లేదా పరిమితం చేస్తుంది\n\n"<annotation id="url">"మరింత తెలుసుకోండి"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి, బ్యాటరీ సేవర్ వీటిని చేస్తుంది:\n·ముదురు రంగు థీమ్ను ఆన్ చేస్తుంది\n·బ్యాక్గ్రౌండ్ కార్యకలాపం, కొన్ని విజువల్ ఎఫెక్ట్స్లతో పాటు “Ok Google” వంటి ఇతర ఫీచర్లను ఆపివేస్తుంది లేదా పరిమితం చేస్తుంది"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"డేటా వినియోగాన్ని తగ్గించడంలో డేటా సేవర్ సహాయకరంగా ఉంటుంది. బ్యాక్గ్రౌండ్లో కొన్ని యాప్లు డేటాను పంపకుండా లేదా స్వీకరించకుండా నిరోధిస్తుంది. మీరు ప్రస్తుతం ఉపయోగిస్తోన్న యాప్, డేటాను యాక్సెస్ చేయగలదు. కానీ తక్కువ సార్లు మాత్రమే అలా చేయవచ్చు. ఉదాహరణకు, మీరు నొక్కే వరకు ఫోటోలు ప్రదర్శించబడవు."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"డేటా సేవర్ను ఆన్ చేయాలా?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ఆన్ చేయి"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"నోటిఫికేషన్లు"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"శీఘ్ర సెట్టింగ్లు"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"పవర్ డైలాగ్ను తెరువు"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"స్క్రీన్ విభజనను టోగుల్ చేయి"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"స్క్రీన్ను లాక్ చేయి"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"స్క్రీన్షాట్"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"యాక్సెసిబిలిటీ మెను"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> క్యాప్షన్ బార్."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> పరిమితం చేయబడిన బకెట్లో ఉంచబడింది"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"సంభాషణ"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"గ్రూప్ సంభాషణ"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index ff5557de5e91..6b8b9121fc62 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"ระบบจะลบข้อมูลในอุปกรณ์ของคุณ"</string> <string name="factory_reset_message" msgid="2657049595153992213">"ใช้แอปผู้ดูแลระบบนี้ไม่ได้ ขณะนี้ระบบจะลบข้อมูลในอุปกรณ์ของคุณ\n\nโปรดติดต่อผู้ดูแลระบบขององค์กรหากมีคำถาม"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ปิดใช้การพิมพ์แล้ว"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"เลิกบล็อกแอปส่วนตัว"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"ระบบจะบล็อกแอปพรุ่งนี้"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"ผู้ดูแลระบบไอทีไม่อนุญาตให้หยุดโปรไฟล์งานชั่วคราวเกิน <xliff:g id="DAYS">%1$d</xliff:g> วัน"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"เปิดโปรไฟล์งาน"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"แอปส่วนตัวจะถูกบล็อกไว้จนกว่าคุณจะเปิดโปรไฟล์งาน"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"แอปส่วนตัวจะถูกบล็อกในวันพรุ่งนี้"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"เปิดโปรไฟล์งาน"</string> <string name="me" msgid="6207584824693813140">"ฉัน"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ตัวเลือกของแท็บเล็ต"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 2-3 วินาทีจะเปิด <xliff:g id="SERVICE">%1$s</xliff:g> ซึ่งเป็นฟีเจอร์การช่วยเหลือพิเศษ การดำเนินการนี้อาจเปลี่ยนแปลงลักษณะการทำงานของอุปกรณ์\n\nคุณแก้ไขทางลัดนี้ให้เปิดฟีเจอร์อื่นได้ในการตั้งค่า > การช่วยเหลือพิเศษ"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"เปิด"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ไม่ต้องเปิด"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"เปิด"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ปิด"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"อนุญาตให้ <xliff:g id="SERVICE">%1$s</xliff:g> ควบคุมอุปกรณ์อย่างเต็มที่ไหม"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"หากคุณเปิด <xliff:g id="SERVICE">%1$s</xliff:g> อุปกรณ์ของคุณจะไม่ใช้ล็อกหน้าจอเพื่อปรับปรุงการเข้ารหัสข้อมูล"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"การควบคุมอย่างเต็มที่เหมาะสำหรับแอปที่ช่วยคุณในเรื่องความต้องการความช่วยเหลือพิเศษแต่ไม่เหมาะสำหรับแอปส่วนใหญ่"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"อัปเดตโดยผู้ดูแลระบบ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ลบโดยผู้ดูแลระบบ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ตกลง"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"โหมดประหยัดแบตเตอรี่จะดำเนินการดังต่อไปนี้เพื่อยืดอายุการใช้งานแบตเตอรี่\n·เปิดธีมมืด\n·ปิดหรือจำกัดกิจกรรมในเบื้องหลัง เอฟเฟกต์ภาพบางอย่าง และฟีเจอร์อื่นๆ อย่างเช่น “Ok Google”\n\n"<annotation id="url">"ดูข้อมูลเพิ่มเติม"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"โหมดประหยัดแบตเตอรี่จะดำเนินการดังต่อไปนี้เพื่อยืดอายุการใช้งานแบตเตอรี่\n·เปิดธีมมืด\n·ปิดหรือจำกัดกิจกรรมในเบื้องหลัง เอฟเฟกต์ภาพบางอย่าง และฟีเจอร์อื่นๆ อย่างเช่น “Ok Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"เพื่อช่วยลดปริมาณการใช้อินเทอร์เน็ต โปรแกรมประหยัดอินเทอร์เน็ตจะช่วยป้องกันไม่ให้บางแอปส่งหรือรับข้อมูลโดยการใช้อินเทอร์เน็ตอยู่เบื้องหลัง แอปที่คุณกำลังใช้งานสามารถเข้าถึงอินเทอร์เน็ตได้ แต่อาจไม่บ่อยเท่าเดิม ตัวอย่างเช่น ภาพต่างๆ จะไม่แสดงจนกว่าคุณจะแตะที่ภาพเหล่านั้น"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"เปิดการประหยัดอินเทอร์เน็ตไหม"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"เปิด"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"การแจ้งเตือน"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"การตั้งค่าด่วน"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"กล่องโต้ตอบพลังงาน"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"เปิด/ปิดการแบ่งหน้าจอ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"หน้าจอล็อก"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ภาพหน้าจอ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"เมนูการช่วยเหลือพิเศษ"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"แถบคำบรรยาย <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"ใส่ <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ในที่เก็บข้อมูลที่ถูกจำกัดแล้ว"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"การสนทนา"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"บทสนทนากลุ่ม"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 5de452546922..f078b82de89b 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Buburahin ang iyong device"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Hindi magamit ang admin app. Mabubura na ang iyong device.\n\nKung mayroon kang mga tanong, makipag-ugnayan sa admin ng iyong organisasyon."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Na-disable ng <xliff:g id="OWNER_APP">%s</xliff:g> ang pag-print."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"I-unblock ang iyong mga personal na app"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Iba-block ang mga app bukas"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Hindi pinapayagan ng IT admin mo na ma-pause ang iyong profile sa trabaho sa loob ng mahigit <xliff:g id="DAYS">%1$d</xliff:g> (na) araw"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"I-on ang profile sa trabaho"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Naka-block ang iyong mga personal na app hangga\'t hindi mo ino-on ang profile sa trabaho mo"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Maba-block ang iyong mga personal na app bukas"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"I-on ang profile sa trabaho"</string> <string name="me" msgid="6207584824693813140">"Ako"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Mga pagpipilian sa tablet"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Mao-on ang feature ng pagiging accessible na <xliff:g id="SERVICE">%1$s</xliff:g> kapag pinindot nang matagal ang parehong volume key nang ilang segundo. Posibleng mabago nito ang paggana ng iyong device.\n\nPuwede mong palitan ng ibang feature ang shortcut na ito sa Mga Setting > Pagiging Accessible."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"I-on"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Huwag i-on"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"NAKA-ON"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NAKA-OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Bigyan ang <xliff:g id="SERVICE">%1$s</xliff:g> ng ganap na kontrol sa iyong device?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Kung io-on mo ang <xliff:g id="SERVICE">%1$s</xliff:g>, hindi gagamitin ng iyong device ang lock ng screen mo para pahusayin ang pag-encrypt ng data."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Naaangkop ang ganap na kontrol sa mga app na tumutulong sa mga pangangailangan mo sa accessibility, pero hindi sa karamihan ng mga app."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Na-update ng iyong admin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Na-delete ng iyong admin"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Para patagalin ang baterya, ginagawa ng Pangtipid sa Baterya na:\n·I-on ang Madilim na tema\n·I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”\n\n"<annotation id="url">"Matuto pa"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Para patagalin ang baterya, ginagawa ng Pangtipid sa Baterya na:\n·I-on ang Madilim na tema\n·I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Upang makatulong na mabawasan ang paggamit ng data, pinipigilan ng Data Saver ang ilang app na magpadala o makatanggap ng data sa background. Maaaring mag-access ng data ang isang app na ginagamit mo sa kasalukuyan, ngunit mas bihira na nito magagawa iyon. Halimbawa, maaaring hindi lumabas ang mga larawan hangga\'t hindi mo nata-tap ang mga ito."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"I-on ang Data Saver?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"I-on"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Mga Notification"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Mga Mabilisang Setting"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialog ng Power"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"I-toggle ang Split Screen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Menu ng Accessibility"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar ng <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Inilagay ang <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> sa PINAGHIHIGPITANG bucket"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Pag-uusap"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Panggrupong Pag-uusap"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index b10d19323066..a0ff1a81d8d4 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız silinecek"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Yönetim uygulaması kullanılamıyor. Cihazınız şimdi silinecek.\n\nSorularınız varsa kuruluşunuzun yöneticisine başvurun."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Yazdırma işlemi <xliff:g id="OWNER_APP">%s</xliff:g> tarafından devre dışı bırakıldı."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Kişisel uygulamalarınızın engellemesini kaldırın"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Uygulamalar yarın engellenecek"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"BT yöneticiniz, iş profilinizin <xliff:g id="DAYS">%1$d</xliff:g> günden fazla duraklatılmasına izin vermiyor"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"İş profilinizi açın"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"İş profilinizi açana kadar kişisel uygulamalarınız engellendi"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Kişisel uygulamalarınız yarın engellenecek"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"İş profilini aç"</string> <string name="me" msgid="6207584824693813140">"Ben"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tablet seçenekleri"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ses tuşlarının ikisini birden birkaç saniyeliğine basılı tutmak <xliff:g id="SERVICE">%1$s</xliff:g> erişilebilirlik özelliğini etkinleştirir. Bu, cihazınızın çalışma şeklini değiştirebilir.\n\nBu kısayolu, Ayarlar > Erişilebilirlik\'te başka bir özellikle değiştirebilirsiniz."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Etkinleştir"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Etkinleştirme"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AÇIK"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"KAPALI"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> hizmetinin cihazınızı tamamen kontrol etmesine izin veriyor musunuz?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> hizmetini açarsanız cihazınız veri şifrelemeyi geliştirmek için ekran kilidinizi kullanmaz."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Erişebilirlik ihtiyaçlarınıza yardımcı olan uygulamalara tam kontrol verilmesi uygundur ancak diğer pek çok uygulama için uygun değildir."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Yöneticiniz tarafından güncellendi"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Yöneticiniz tarafından silindi"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Tamam"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Pil ömrünü uzatmak için Pil Tasarrufu:\n·Koyu temayı açar\n·Arka plan etkinliğini, bazı görsel efektleri ve \"Hey Google\" gibi diğer özellikleri kapatır veya kısıtlar\n\n"<annotation id="url">"Daha fazla bilgi"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Pil ömrünü uzatmak için Pil Tasarrufu:\n·Koyu temayı açar\n·Arka plan etkinliğini, bazı görsel efektleri ve \"Hey Google\" gibi diğer özellikleri kapatır veya kısıtlar"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Veri kullanımını azaltmaya yardımcı olması için Veri Tasarrufu, bazı uygulamaların arka planda veri göndermesini veya almasını engeller. Şu anda kullandığınız bir uygulama veri bağlantısına erişebilir, ancak bunu daha seyrek yapabilir. Bu durumda örneğin, siz resimlere dokunmadan resimler görüntülenmez."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Veri Tasarrufu açılsın mı?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aç"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Bildirimler"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Hızlı Ayarlar"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Güç İletişim Kutusu"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bölünmüş Ekranı aç/kapat"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Kilit Ekranı"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekran görüntüsü"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Erişilebilirlik Menüsü"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasının başlık çubuğu."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> KISITLANMIŞ gruba yerleştirildi"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Görüşme"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grup Görüşmesi"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 55d6eca30d89..da529bc989bb 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -204,9 +204,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"З вашого пристрою буде стерто всі дані"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Не можна запускати додаток для адміністраторів. Буде відновлено заводські налаштування пристрою.\n\nЯкщо у вас є запитання, зв’яжіться з адміністратором своєї організації."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Додаток <xliff:g id="OWNER_APP">%s</xliff:g> вимкнув друк."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Розблокуйте особисті додатки"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Додатки буде заблоковано завтра"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Ваш ІТ-адміністратор не дозволяє призупиняти робочий профіль більше ніж на <xliff:g id="DAYS">%1$d</xliff:g> дн."</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Увімкніть робочий профіль"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Особисті додатки заблоковано, доки ви не ввімкнете робочий профіль"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Завтра буде заблоковано ваші особисті додатки"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Увімкнути робочий профіль"</string> <string name="me" msgid="6207584824693813140">"Я"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Парам. пристрою"</string> @@ -1675,6 +1675,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Якщо втримувати обидві клавіші гучності впродовж кількох секунд, буде ввімкнено спеціальні можливості – <xliff:g id="SERVICE">%1$s</xliff:g>. Це може вплинути на роботу пристрою.\n\nДля цієї комбінації клавіш можна вибрати іншу функцію в меню \"Налаштування > Спеціальні можливості\"."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Увімкнути"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Не вмикати"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"УВІМК."</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ВИМК."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Надати сервісу <xliff:g id="SERVICE">%1$s</xliff:g> повний доступ до вашого пристрою?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Якщо ви ввімкнете сервіс <xliff:g id="SERVICE">%1$s</xliff:g>, дані на пристрої не захищатимуться екраном блокування."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Повний доступ доречний для додатків, які надають спеціальні можливості, але його не варто відкривати для більшості інших додатків."</string> @@ -1838,8 +1840,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Оновлено адміністратором"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Видалено адміністратором"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Щоб подовжити час роботи акумулятора, режим енергозбереження:\n·вмикає темну тему;\n·припиняє або обмежує фонову активність, вимикає деякі візуальні ефекти й інші енергозатратні функції, зокрема Ok Google.\n\n"<annotation id="url">"Докладніше"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Щоб подовжити час роботи акумулятора, режим енергозбереження:\n·вмикає темну тему;\n·припиняє або обмежує фонову активність, вимикає деякі візуальні ефекти й інші енергозатратні функції, зокрема команду \"Ok Google\"."</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Щоб зменшити використання трафіку, функція \"Заощадження трафіку\" не дозволяє деяким додаткам надсилати чи отримувати дані у фоновому режимі. Поточний додаток зможе отримувати доступ до таких даних, але рідше. Наприклад, зображення не відображатиметься, доки ви не торкнетеся його."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Увімкнути заощадження трафіку?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Увімкнути"</string> @@ -2106,13 +2110,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Сповіщення"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Швидкі налаштування"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Відкрити вікно"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Розділити екран"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заблокувати екран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Знімок екрана"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Меню спеціальних можливостей"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Смуга із субтитрами для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" додано в сегмент з обмеженнями"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Чат"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Груповий чат"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index d4728a107446..0f09c611cacd 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"آپ کا آلہ صاف کر دیا جائے گا"</string> <string name="factory_reset_message" msgid="2657049595153992213">"منتظم کی ایپ استعمال نہیں کی جا سکتی۔ آپ کا آلہ اب مٹا دیا جائے گا۔\n\nاگر آپ کے سوالات ہیں تو اپنی تنظیم کے منتظم سے رابطہ کریں۔"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> نے پرنٹنگ کو غیر فعال کر دیا ہے۔"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"اپنے ذاتی ایپس غیر مسدود کریں"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"آئندہ کل ایپس کو مسدود کر دیا جائے گا"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"آپ کا IT منتظم آپ کی دفتری پروفائل کو <xliff:g id="DAYS">%1$d</xliff:g> دن سے زیادہ موقوف ہونے کی اجازت نہیں دیتا ہے"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"اپنی دفتری پروفائل آن کریں"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"آپ کے ذاتی ایپس کو اس وقت تک بلاک کر دیا جاتا ہے جب تک کہ آپ اپنے ورک پروفایل کو آن نہیں کرتے"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"آئندہ کل آپ کی ذاتی ایپس کو مسدود کر دیا جائے گا"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"دفتری پروفائل آن کریں"</string> <string name="me" msgid="6207584824693813140">"میں"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"ٹیبلیٹ کے اختیارات"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"والیوم کی دونوں کلیدوں کو کچھ سیکنڈز تک دبائے رکھنے سے <xliff:g id="SERVICE">%1$s</xliff:g> ایکسیسبیلٹی خصوصیت آن ہو جاتی ہے۔ اس سے آپ کے آلے کے کام کرنے کا طریقہ تبدیل ہو سکتا ہے۔\n\nآپ ترتیبات اور ایکسیسبیلٹی میں دیگر خصوصیت کے لیے اس شارٹ کٹ کو تبدیل کر سکتے ہیں۔"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"آن کریں"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"آن نہ کریں"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"آن"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"آف"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> کو آپ کے آلے کا مکمل کنٹرول حاصل کرنے کی اجازت دیں؟"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"اگر آپ <xliff:g id="SERVICE">%1$s</xliff:g> کو آن کرتے ہیں تو آپ کا آلہ ڈیٹا کی مرموزکاری کو بڑھانے کیلئے آپ کی اسکرین کا قفل استعمال نہیں کرے گا۔"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"مکمل کنٹرول ان ایپس کے لیے مناسب ہے جو ایکسیسبیلٹی کی ضروریات میں آپ کی مدد کرتی ہیں، لیکن زیادہ تر ایپس کیلئے مناسب نہیں۔"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"آپ کے منتظم کے ذریعے اپ ڈیٹ کیا گیا"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"آپ کے منتظم کے ذریعے حذف کیا گیا"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ٹھیک ہے"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"بیٹری لائف کو بڑھانے کے لیے، بیٹری سیور:\n گہری تھیم کو آن کرتی ہے\n پس منظر کی سرگرمی، کچھ بصری اثرات اور دیگر خصوصیات جیسے کہ \"Ok Google\" کو آف یا محدود کرتی ہے\n\n"<annotation id="url">"مزید جانیں"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"بیٹری لائف کو بڑھانے کے لیے، بیٹری سیور:\n گہری تھیم کو آن کرتی ہے\n پس منظر کی سرگرمی، کچھ بصری اثرات اور دیگر خصوصیات جیسے کہ \"Ok Google\" کو آف یا محدود کرتی ہے"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"ڈیٹا کے استعمال کو کم کرنے میں مدد کیلئے، ڈیٹا سیور پس منظر میں کچھ ایپس کو ڈیٹا بھیجنے یا موصول کرنے سے روکتی ہے۔ آپ جو ایپ فی الحال استعمال کر رہے ہیں وہ ڈیٹا تک رسائی کر سکتی ہے مگر ہو سکتا ہے ایسا اکثر نہ ہو۔ اس کا مطلب مثال کے طور پر یہ ہو سکتا ہے کہ تصاویر تھپتھپانے تک ظاہر نہ ہوں۔"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"ڈیٹا سیور آن کریں؟"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"آن کریں"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"اطلاعات"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"فوری ترتیبات"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"پاور ڈائیلاگ"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"اسپلٹ اسکرین ٹوگل کریں"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"مقفل اسکرین"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"اسکرین شاٹ"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"ایکسیسبیلٹی مینو"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> کی کیپشن بار۔"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> کو پابند کردہ بکٹ میں رکھ دیا گیا ہے"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"گفتگو"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"گروپ گفتگو"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"+<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index c212627a3206..d069a68084b7 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Qurilmangizdagi ma’lumotlar o‘chirib tashlanadi"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Administrator ilovasini ishlatib bo‘lmaydi. Qurilmada barcha ma’lumotlar o‘chirib tashlanadi.\n\nSavollaringiz bo‘lsa, administrator bilan bog‘laning."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Chop etish funksiyasi <xliff:g id="OWNER_APP">%s</xliff:g> tomonidan faolsizlantirilgan."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Shaxsiy ilovalarni blokdan chiqaring"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Ilovalar ertaga bloklanadi"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"AT administratoringiz ish profili <xliff:g id="DAYS">%1$d</xliff:g> kundan ortiq pauza qilinishini taqiqlagan"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Ish profilingizni yoqing"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Ish profilingiz yoniqligida shaxsiy ilovalaringiz bloklanadi"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Shaxsiy ilovalaringiz ertaga bloklanadi"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Ish profilini yoqish"</string> <string name="me" msgid="6207584824693813140">"Men"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Planshet sozlamalari"</string> @@ -1107,8 +1107,8 @@ <string name="deleteText" msgid="4200807474529938112">"O‘chirish"</string> <string name="inputMethod" msgid="1784759500516314751">"Kiritish uslubi"</string> <string name="editTextMenuTitle" msgid="857666911134482176">"Matn yozish"</string> - <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Xotirada bo‘sh joy tugamoqda"</string> - <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Ba‘zi tizim funksiyalari ishlamasligi mumkin"</string> + <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Xotirada joy yetarli emas"</string> + <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Ayrim funksiyalar ishlamasligi mumkin"</string> <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Tizim uchun xotirada joy yetarli emas. Avval 250 megabayt joy bo‘shatib, keyin qurilmani o‘chirib yoqing."</string> <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> ishlamoqda"</string> <string name="app_running_notification_text" msgid="5120815883400228566">"Ilovani to‘xtatish yoki qo‘shimcha ma’lumot olish uchun bosing."</string> @@ -1314,8 +1314,8 @@ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Wi-Fi orqali debaggingni faolsizlantirish uchun bosing."</string> <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Xavfsizlik sinovi rejimi yoqildi"</string> <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string> - <string name="console_running_notification_title" msgid="6087888939261635904">"Davomiy port terminali yoqildi"</string> - <string name="console_running_notification_message" msgid="7892751888125174039">"Samaradorlik pasaydi. Terminalni faolsizlantirish uchun operatsion tizim yuklagichini oching."</string> + <string name="console_running_notification_title" msgid="6087888939261635904">"Ketma-ket port konsoli yoqildi"</string> + <string name="console_running_notification_message" msgid="7892751888125174039">"Qurilma samaradorligi pasaydi. Konsolni faolsizlantirish uchun operatsion tizim yuklagichini oching."</string> <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"USB portda suyuqlik yoki parcha bor"</string> <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB port avtomatik tarzda faolsizlashtirildi. Batafsil axborot olish uchun bosing."</string> <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"USB portdan foydalanish mumkin"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"<xliff:g id="SERVICE">%1$s</xliff:g> funksiyasini yoqish uchun ikkala tovush tugmalarini bir necha soniya bosib turing. Qurilmangiz ishlashida oʻzgarish yuz berishi mumkin.\n\nBu tezkor tugmalarni boshqa funksiyaga Sozlamalar ichidagi Maxsus imkoniyatlar orqali tayinlash mumkin."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Yoqilsin"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Yoqilmasin"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"YONIQ"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"YOQILMAGAN"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> xizmatiga qurilmangizni boshqarish uchun toʻliq ruxsat berilsinmi?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Agar <xliff:g id="SERVICE">%1$s</xliff:g> xizmatini yoqsangiz, qurilmangiz maʼlumotlarni shifrlashni kuchaytirish uchun ekran qulfidan foydalanmaydi."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Toʻliq nazorat maxsus imkoniyatlar bilan ishlovchi ilovalar uchun mos, lekin barcha ilovalar uchun emas."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Administrator tomonidan yangilangan"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administrator tomonidan o‘chirilgan"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Batareya quvvatini uzaytirish uchun Quvvat tejash funksiyasi:\n·Tungi mavzuni yoqadi\n·Fondagi harakatlar, vizual effektlar va “Hey Google” kabi boshqa funksiyalarni faolsizlantiradi\n\n"<annotation id="url">"Batafsil"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Batareya quvvatini uzaytirish uchun Quvvat tejash funksiyasi:\n·Tungi mavzuni yoqadi\n·Fondagi harakatlar, vizual effektlar va “Hey Google” kabi boshqa funksiyalarni faolsizlantiradi"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Trafik tejash rejimida ayrim ilovalar uchun orqa fonda internetdan foydalanish imkoniyati cheklanadi. Siz ishlatayotgan ilova zaruratga qarab internet-trafik sarflashi mumkin, biroq cheklangan miqdorda. Masalan, rasmlar ustiga bosmaguningizcha ular yuklanmaydi."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Trafik tejash yoqilsinmi?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Yoqish"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Bildirishnomalar"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Tezkor sozlamalar"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Quvvat muloqot oynasi"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ekranni ikkiga ajratish tugmasi"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekran qulfi"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skrinshot"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Maxsus imkoniyatlar menyusi"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> taglavhalar paneli."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> cheklangan turkumga joylandi"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Suhbat"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Guruh suhbati"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 3b2de1c5e691..479574b6a5df 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Thiết bị của bạn sẽ bị xóa"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Không thể sử dụng ứng dụng quản trị. Thiết bị của bạn sẽ bị xóa ngay bây giờ.\n\nHãy liên hệ với quản trị viên của tổ chức nếu bạn có thắc mắc."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> đã tắt tính năng in."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Bỏ chặn ứng dụng cá nhân của bạn"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Các ứng dụng sẽ bị chặn vào ngày mai"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Quản trị viên CNTT không cho phép bạn tạm dừng hồ sơ công việc quá <xliff:g id="DAYS">%1$d</xliff:g> ngày"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Bật hồ sơ công việc của bạn"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Ứng dụng cá nhân của bạn bị chặn cho tới khi bạn bật hồ sơ công việc"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Ứng dụng cá nhân của bạn sẽ bị chặn vào ngày mai"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Bật hồ sơ công việc"</string> <string name="me" msgid="6207584824693813140">"Tôi"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Tùy chọn máy tính bảng"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Thao tác nhấn và giữ cả hai phím âm lượng trong vài giây sẽ bật <xliff:g id="SERVICE">%1$s</xliff:g>, một tính năng hỗ trợ tiếp cận. Việc bật tính năng này có thể thay đổi cách thiết bị của bạn hoạt động.\n\nBạn có thể chuyển phím tắt này thành một tính năng khác trong phần Cài đặt > Hỗ trợ tiếp cận."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Bật"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Không bật"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ĐANG BẬT"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ĐANG TẮT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Cho phép <xliff:g id="SERVICE">%1$s</xliff:g> toàn quyền kiểm soát thiết bị của bạn?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Nếu bạn bật <xliff:g id="SERVICE">%1$s</xliff:g>, thiết bị của bạn sẽ không dùng phương thức khóa màn hình để tăng cường mã hóa dữ liệu."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Bạn chỉ nên cấp toàn quyền kiểm soát cho những ứng dụng trợ giúp mình khi cần hỗ trợ tiếp cận, chứ không nên cấp cho hầu hết các ứng dụng."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Do quản trị viên của bạn cập nhật"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Do quản trị viên của bạn xóa"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Để tăng thời lượng pin, Trình tiết kiệm pin sẽ:\n·Bật Giao diện tối\n·Tắt hoặc hạn chế hoạt động chạy trong nền, một số hiệu ứng hình ảnh và các tính năng khác như lệnh “Ok Google”\n\n"<annotation id="url">"Tìm hiểu thêm"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Để tăng thời lượng pin, Trình tiết kiệm pin sẽ:\n·Bật giao diện tối\n·Tắt hoặc hạn chế hoạt động chạy trong nền, một số hiệu ứng hình ảnh và các tính năng khác như lệnh “Ok Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Để giúp giảm mức sử dụng dữ liệu, Trình tiết kiệm dữ liệu sẽ chặn một số ứng dụng gửi hoặc nhận dữ liệu trong nền. Ứng dụng mà bạn hiện sử dụng có thể dùng dữ liệu nhưng tần suất sẽ giảm. Ví dụ: hình ảnh sẽ không hiển thị cho đến khi bạn nhấn vào hình ảnh đó."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Bật Trình tiết kiệm dữ liệu?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Bật"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Thông báo"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Cài đặt nhanh"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Hộp thoại thao tác với nguồn"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bật/tắt chế độ chia đôi màn hình"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Khóa màn hình"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Chụp ảnh màn hình"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Trình đơn Hỗ trợ tiếp cận"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Thanh phụ đề của <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Đã đưa <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> vào bộ chứa BỊ HẠN CHẾ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Cuộc trò chuyện"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Cuộc trò chuyện nhóm"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index dd8875944a10..7f54194d6ae6 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"系统将清空您的设备"</string> <string name="factory_reset_message" msgid="2657049595153992213">"无法使用管理应用,系统现在将清空您的设备。\n\n如有疑问,请与您所在单位的管理员联系。"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"“<xliff:g id="OWNER_APP">%s</xliff:g>”已停用打印功能。"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"取消屏蔽个人应用"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"应用将于明日被屏蔽"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"您的 IT 管理员不允许工作资料的暂停时间超过 <xliff:g id="DAYS">%1$d</xliff:g> 天"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"开启工作资料"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"系统已屏蔽您的个人应用。您需要开启工作资料,系统才会取消屏蔽这些应用"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"系统将于明天屏蔽您的个人应用"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"开启工作资料"</string> <string name="me" msgid="6207584824693813140">"我"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"平板电脑选项"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"同时按住两个音量键几秒钟,即可开启<xliff:g id="SERVICE">%1$s</xliff:g>无障碍功能。这样做可能会改变您设备的工作方式。\n\n您可以在“设置”>“无障碍”中将此快捷方式更改为开启另一项功能。"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"开启"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"不开启"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"开启"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"关闭"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要允许<xliff:g id="SERVICE">%1$s</xliff:g>完全控制您的设备吗?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"如果您开启<xliff:g id="SERVICE">%1$s</xliff:g>,您的设备将无法使用屏幕锁定功能来增强数据加密效果。"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"对于能满足您的无障碍功能需求的应用,可授予其完全控制权限;但对大部分应用来说,都不适合授予此权限。"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"已由您的管理员更新"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由您的管理员删除"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"确定"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"为了延长电池续航时间,省电模式会执行以下操作:\n开启深色主题\n关闭或限制后台活动、部分视觉效果和其他功能,例如“Ok Google”\n\n"<annotation id="url">"了解详情"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"为了延长电池续航时间,省电模式会执行以下操作:\n开启深色主题\n关闭或限制后台活动、部分视觉效果和其他功能,例如“Ok Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"为了减少流量消耗,流量节省程序会阻止某些应用在后台收发数据。您当前使用的应用可以收发数据,但频率可能会降低。举例而言,这可能意味着图片只有在您点按之后才会显示。"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"要开启流量节省程序吗?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"开启"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"通知"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"快捷设置"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"电源对话框"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"开启/关闭分屏"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"锁定屏幕"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"屏幕截图"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"无障碍功能菜单"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>的标题栏。"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已被放入受限存储分区"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"对话"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"群组对话"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 4d790c465314..d71d2c5bed6b 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"您的裝置將被清除"</string> <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理員應用程式。系統會現在清除您的裝置。\n\n如有任何疑問,請聯絡您的機構管理員。"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」暫停了列印。"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"解除封鎖您的個人應用程式"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"應用程式將於明天封鎖"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT 管理員不允許您的工作設定檔暫停使用超過 <xliff:g id="DAYS">%1$d</xliff:g> 天"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"開啟工作設定檔"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"系統會封鎖您的個人應用程式,直至您開啟工作設定檔為止"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"您的個人應用程式將於明天封鎖"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"啟用工作設定檔"</string> <string name="me" msgid="6207584824693813140">"我本人"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"平板電腦選項"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"同時按下兩個音量鍵幾秒,以開啟 <xliff:g id="SERVICE">%1$s</xliff:g> 無障礙功能。這可能會變更裝置的運作。\n\n您可在「設定」>「無障礙功能」中變更此快速鍵。"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"開啟"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"不要開啟"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"開啟"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"關閉"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要允許 <xliff:g id="SERVICE">%1$s</xliff:g> 完全控制您的裝置嗎?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"如果您開啟 <xliff:g id="SERVICE">%1$s</xliff:g>,裝置將無法使用螢幕鎖定功能加強資料加密。"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"為您提供所需無障礙功能的應用程式有權完全控制您的裝置,但大部分應用程式均沒有此權限。"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"已由您的管理員更新"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由您的管理員刪除"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"好"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"為延長電池壽命,「省電模式」會:\n開啟深色主題背景\n關閉或限制背景活動、某些視覺效果和其他功能 (例如「Hey Google」)\n\n"<annotation id="url">"瞭解詳情"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"為延長電池壽命,「省電模式」會:\n開啟深色主題背景\n關閉或限制背景活動、某些視覺效果和其他功能 (例如「Hey Google」)"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。您正在使用的應用程式可存取資料,但次數可能會減少。例如,圖片可能需要輕按才會顯示。"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"要開啟「數據節省模式」嗎?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"開啟"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"通知"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"快速設定"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"電源對話框"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"切換分割螢幕"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"將畫面上鎖"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"螢幕截圖"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"無障礙功能選單"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」的說明列。"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已納入受限制的儲存區"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"對話"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"群組對話"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index e18b51e91a2a..3c0312b76ca7 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"你的裝置資料將遭到清除"</string> <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理應用程式,系統現在將清除你裝置中的資料。\n\n如有任何問題,請與貴機構的管理員聯絡。"</string> <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」已停用列印功能。"</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"解除封鎖個人應用程式"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"系統將於明天封鎖應用程式"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"IT 管理員不允許你暫停工作資料夾超過 <xliff:g id="DAYS">%1$d</xliff:g> 天"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"開啟工作資料夾"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"系統已封鎖你的個人應用程式;你必須開啟工作資料夾,這些應用程式才會解除封鎖"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"系統將於明天封鎖你的個人應用程式"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"開啟工作資料夾"</string> <string name="me" msgid="6207584824693813140">"我"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"平板電腦選項"</string> @@ -1299,7 +1299,7 @@ <string name="usb_supplying_notification_title" msgid="5378546632408101811">"正在透過 USB 為連接的裝置充電"</string> <string name="usb_mtp_notification_title" msgid="1065989144124499810">"已開啟 USB 檔案傳輸模式"</string> <string name="usb_ptp_notification_title" msgid="5043437571863443281">"已開啟 USB PTP 模式"</string> - <string name="usb_tether_notification_title" msgid="8828527870612663771">"已開啟 USB 數據連線模式"</string> + <string name="usb_tether_notification_title" msgid="8828527870612663771">"已開啟 USB 網路共用模式"</string> <string name="usb_midi_notification_title" msgid="7404506788950595557">"已開啟 USB MIDI 模式"</string> <string name="usb_accessory_notification_title" msgid="1385394660861956980">"已連接 USB 配件"</string> <string name="usb_notification_message" msgid="4715163067192110676">"輕觸即可查看更多選項。"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"同時按住音量調高鍵和調低鍵數秒,即可開啟「<xliff:g id="SERVICE">%1$s</xliff:g>」無障礙功能。這麼做可能會改變裝置的運作方式。\n\n你可以在 [設定] > [無障礙設定] 中變更這個快速鍵觸發的功能。"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"開啟"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"不要開啟"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"已開啟"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"已關閉"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要將裝置的完整控制權授予「<xliff:g id="SERVICE">%1$s</xliff:g>」嗎?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"如果你開啟「<xliff:g id="SERVICE">%1$s</xliff:g>」,裝置將無法使用螢幕鎖定功能強化資料加密。"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"如果你有無障礙服務需求,可以將完整控制權授予具有相關功能的應用程式,但請勿將完整控制權授予大多數的應用程式。"</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"已由你的管理員更新"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"確定"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"為了延長電池續航力,節約耗電量功能會執行以下動作:\n開啟深色主題\n關閉或限制背景活動、部分視覺效果和其他功能,例如「Hey Google」啟動字詞\n\n"<annotation id="url">"瞭解詳情"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"為了延長電池續航力,節約耗電量功能會執行以下動作:\n· 開啟深色主題\n· 關閉或限制背景活動、部分視覺效果和其他功能,例如「Hey Google」啟動字詞"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。你目前使用的應用程式可以存取資料,但存取頻率可能不如平時高。舉例來說,圖片可能不會自動顯示,在你輕觸後才會顯示。"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"要開啟數據節省模式嗎?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"開啟"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"通知"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"快速設定"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"開啟電源對話方塊"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"切換分割畫面模式"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"螢幕鎖定"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"擷取螢幕畫面"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"無障礙選單"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」的說明文字列。"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"已將「<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>」移入受限制的值區"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"對話"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"群組對話"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index a9af563ee1e5..4acf3fe2d33c 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -200,9 +200,9 @@ <string name="factory_reset_warning" msgid="6858705527798047809">"Idivayisi yakho izosulwa"</string> <string name="factory_reset_message" msgid="2657049595153992213">"Uhlelo lokusebenza lomlawuli alikwazi ukusetshenziswa. Idivayisi yakho manje izosuswa.\n\nUma unemibuzo, xhumana nomlawuli wezinhlangano zakho."</string> <string name="printing_disabled_by" msgid="3517499806528864633">"Ukuphrinta kukhutshazwe nge-<xliff:g id="OWNER_APP">%s</xliff:g>."</string> - <string name="personal_apps_suspended_title" msgid="4543693107104417750">"Vula izinhlelo zakho zokusebenza zomuntu siqu"</string> - <string name="personal_apps_suspended_tomorrow_title" msgid="6414440257969874914">"Izinhlelo zokusebenza zizovinjelwa kusasa"</string> - <string name="personal_apps_suspended_text" msgid="8954038765131038226">"Umphathi wakho we-IT akavumeli ukuthi iphrofayela yakho yasemsebenzini imiswe okwesikhana izinsuku ezingaphezu kwezingu-<xliff:g id="DAYS">%1$d</xliff:g>"</string> + <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Vula iphrofayela yakho yomsebenzi"</string> + <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Izinhlelo zakho zokusebenza zomuntu siqu zivinjelwe kuze kube yilapho uvula iphrofayela yakho yomsebenzi"</string> + <string name="personal_apps_suspension_tomorrow_text" msgid="6322541302153673994">"Izinhlelo zakho zokusebenza zomuntu siqu zizovinjelwa kusasa"</string> <string name="personal_apps_suspended_turn_profile_on" msgid="4278188538997940785">"Vula iphrofayela yomsebenzi"</string> <string name="me" msgid="6207584824693813140">"Mina"</string> <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Okukhethwa kukho kwethebhulethi"</string> @@ -1631,6 +1631,8 @@ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ukubambela phansi bobabili okhiye bevolumu amasekhondi ambalwa kuvula i-<xliff:g id="SERVICE">%1$s</xliff:g>, eyisici sokufinyelela Lokhu kungashintsha indlela idivayisi yakho esebenza ngayo.\n\nUngashintshela lesi sinqamuleli kwesinye isici Kuzilungiselelo > Ukufinyeleleka."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Vula"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ungavuli"</string> + <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"VULA"</string> + <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VALA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vumela i-<xliff:g id="SERVICE">%1$s</xliff:g> ukuthola ukulawula okuphelele kwedivayisi yakho?"</string> <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Uma uvula i-<xliff:g id="SERVICE">%1$s</xliff:g>, idivayisi yakho ngeke isebenzise ukukhiya kwakho kwesikrini sakho ukuthuthukisa ukubethelwa kwedatha."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Ukulawula okugcwele kulungele izinhlelo zokusebenza ezikusiza ngezidingo zokufinyelela, kodwa hhayi izinhlelo zokusebenza eziningi."</string> @@ -1792,8 +1794,10 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Kubuyekezwe umlawuli wakho"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Kususwe umlawuli wakho"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"KULUNGILE"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Ukuze unwebise impilo yebhethri, Isilondolozi Sebhethri:\n·Sivula itimu emnyama\n·Sivala noma sikhawulela umsebenzi wangasemuva, eminye imithelela yokubuka, nezinye izici ezifana nokuthi “Hey Google”\n\n"<annotation id="url">"Funda kabanzi"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Ukuze unwebise impilo yebhethri, Isilondolozi sebhethri:\n·Vula itimu emnyama\n·Vala noma ukhawulele umsebenzi wangasemuva, eminye imithelela yokubuka, nezinye izici ezifana nokuthi “Hey Google”"</string> + <!-- no translation found for battery_saver_description_with_learn_more (5997766757551917769) --> + <skip /> + <!-- no translation found for battery_saver_description (8587408568232177204) --> + <skip /> <string name="data_saver_description" msgid="4995164271550590517">"Ukusiza ukwehlisa ukusetshenziswa kwedatha, iseva yedatha igwema ezinye izinhlelo zokusebenza ukuthi zithumele noma zamukele idatha ngasemuva. Uhlelo lokusebenza olisebenzisa okwamanje lingafinyelela idatha, kodwa lingenza kanjalo kancane. Lokhu kungachaza, isibonelo, ukuthi izithombe azibonisi uze uzithephe."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Vula iseva yedatha?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Vula"</string> @@ -2038,13 +2042,17 @@ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Izaziso"</string> <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Izilungiselelo ezisheshayo"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Ibhokisi lamandla"</string> - <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Guqula ukuhlukanisa isikrini"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Khiya isikrini"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Isithombe-skrini"</string> - <string name="accessibility_system_action_accessibility_menu_label" msgid="8436484650391125184">"Imenyu yokufinyeleleka"</string> + <!-- no translation found for accessibility_system_action_accessibility_button_label (5941347017132886642) --> + <skip /> + <!-- no translation found for accessibility_system_action_accessibility_button_chooser_label (6973618519666227981) --> + <skip /> <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Ibha yamazwibela we-<xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"I-<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ifakwe kubhakede LOKUKHAWULELWE"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> + <!-- no translation found for conversation_single_line_image_placeholder (6983271082911936900) --> + <skip /> <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Ingxoxo"</string> <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Ingxoxo Yeqembu"</string> <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index ab79d2d91070..b91d35b604ca 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2864,7 +2864,6 @@ <item>lockdown</item> <item>logout</item> <item>bugreport</item> - <item>screenshot</item> </string-array> <!-- Number of milliseconds to hold a wake lock to ensure that drawing is fully diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index e4aef861198a..bbe547b597f5 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -708,14 +708,11 @@ <dimen name="conversation_face_pile_protection_width">2dp</dimen> <!-- The width of the protection of the face pile layout when expanded--> <dimen name="conversation_face_pile_protection_width_expanded">1dp</dimen> - <!-- The padding of the expanded message container when the app name is gone--> - <dimen name="expanded_group_conversation_message_padding_without_app_name">14dp</dimen> + <!-- The padding of the expanded message container--> + <dimen name="expanded_group_conversation_message_padding">14dp</dimen> <!-- The top padding of the conversation icon container in the regular state--> - <dimen name="conversation_icon_container_top_padding">12dp</dimen> - - <!-- The top padding of the conversation icon container when there's no app name present in a group--> - <dimen name="conversation_icon_container_top_padding_no_app_name">9dp</dimen> + <dimen name="conversation_icon_container_top_padding">9dp</dimen> <!-- The top padding of the conversation icon container when the avatar is small--> <dimen name="conversation_icon_container_top_padding_small_avatar">17.5dp</dimen> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 0e40c988164a..33dd81dca33e 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -442,19 +442,19 @@ <string name="printing_disabled_by">Printing disabled by <xliff:g id="owner_app">%s</xliff:g>.</string> <!-- Notification title. This notification lets a user know that their personal apps are - blocked due to a work policy from their IT admin, and tells them what they need to do - to unblock their apps.[CHAR LIMIT=29] --> - <string name="personal_apps_suspended_title">Unblock your personal apps</string> - <!-- Notification title. This notification lets a user know that their apps will be blocked - tomorrow due to a work policy from their IT admin, and tells them what they need to do to - prevent the apps from being blocked. [CHAR LIMIT=29] --> - <string name="personal_apps_suspended_tomorrow_title">Apps will be blocked tomorrow</string> - <!-- Notification text. This notification lets a user know that they need to turn on their - work profile due to a work policy from their IT admin. The number of days is at least 3. - [CHAR LIMIT=NONE] --> - <string name="personal_apps_suspended_text">Your IT admin doesn\u2019t allow your - work profile to be paused for more than <xliff:g id="days" example="3">%1$d</xliff:g> - days</string> + either blocked or will be blocked soon due to a work policy from their IT admin, and that + they need to turn on their work profile to unblock their apps.[CHAR LIMIT=29] --> + <string name="personal_apps_suspension_title">Turn on your work profile</string> + <!-- Notification text. This notification lets a user know that their personal apps are + blocked due to a work policy from their IT admin, and that they need to turn on their work + profile to unblock their apps.[CHAR LIMIT=NONE] --> + <string name="personal_apps_suspension_text"> + Your personal apps are blocked until you turn on your work profile</string> + <!-- Notification text. This notification lets a user know that their apps will be blocked + tomorrow due to a work policy from their IT admin, and that they need to turn on their work + profile to prevent the apps from being blocked. [CHAR LIMIT=NONE] --> + <string name="personal_apps_suspension_tomorrow_text"> + Your personal apps will be blocked tomorrow</string> <!-- Title for the button that turns work profile on. To be used in a notification [CHAR LIMIT=NONE] --> <string name="personal_apps_suspended_turn_profile_on">Turn on work profile</string> @@ -4410,6 +4410,12 @@ shortcut enabled. [CHAR LIMIT=none] --> <string name="accessibility_shortcut_off">Don’t turn on</string> + <!-- Text for a feature status that is enabled. [CHAR LIMIT=20] --> + <string name="accessibility_shortcut_menu_item_status_on">ON</string> + + <!-- Text for a feature status that is disabled. [CHAR LIMIT=20] --> + <string name="accessibility_shortcut_menu_item_status_off">OFF</string> + <!-- Title for a warning about security implications of enabling an accessibility service. [CHAR LIMIT=NONE] --> <string name="accessibility_enable_service_title">Allow @@ -4836,10 +4842,10 @@ <string name="confirm_battery_saver">OK</string> <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. --> - <string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string> + <string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n\n\u2022Turns on Dark theme\n\u2022Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string> <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. --> - <string name="battery_saver_description">To extend battery life, Battery Saver:\n·Turns on Dark theme\n·Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d</string> + <string name="battery_saver_description">To extend battery life, Battery Saver:\n\n\u2022Turns on Dark theme\n\u2022Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d</string> <!-- [CHAR_LIMIT=NONE] Data saver: Feature description --> <string name="data_saver_description">To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them.</string> @@ -5431,14 +5437,14 @@ <string name="accessibility_system_action_quick_settings_label">Quick Settings</string> <!-- Label for opening power dialog action [CHAR LIMIT=NONE] --> <string name="accessibility_system_action_power_dialog_label">Power Dialog</string> - <!-- Label for toggle split screen action [CHAR LIMIT=NONE] --> - <string name="accessibility_system_action_toggle_split_screen_label">Toggle Split Screen</string> <!-- Label for lock screen action [CHAR LIMIT=NONE] --> <string name="accessibility_system_action_lock_screen_label">Lock Screen</string> <!-- Label for taking screenshot action [CHAR LIMIT=NONE] --> <string name="accessibility_system_action_screenshot_label">Screenshot</string> - <!-- Label for showing accessibility menu action [CHAR LIMIT=NONE] --> - <string name="accessibility_system_action_accessibility_menu_label">Accessibility Menu</string> + <!-- Label for showing accessibility shortcut action [CHAR LIMIT=NONE] --> + <string name="accessibility_system_action_accessibility_button_label">On-screen Accessibility Shortcut</string> + <!-- Label for showing accessibility shortcut menu action [CHAR LIMIT=NONE] --> + <string name="accessibility_system_action_accessibility_button_chooser_label">On-screen Accessibility Shortcut Chooser</string> <!-- Accessibility description of caption view --> <string name="accessibility_freeform_caption">Caption bar of <xliff:g id="app_name">%1$s</xliff:g>.</string> @@ -5449,6 +5455,9 @@ <!-- The way a conversation name is displayed when single line. The text will be displayed to the end of this text with some spacing --> <string name="conversation_single_line_name_display"><xliff:g id="sender_name" example="Sara">%1$s</xliff:g>:</string> + <!-- Text used when a conversation is displayed in a single-line when the latest message is an image. [CHAR_LIMIT=NONE] --> + <string name="conversation_single_line_image_placeholder">sent an image</string> + <!-- Conversation Title fallback if the there is no name provided in a 1:1 conversation [CHAR LIMIT=40]--> <string name="conversation_title_fallback_one_to_one">Conversation</string> diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml index 64768cf4c730..e9ac679ec39c 100644 --- a/core/res/res/values/styles_device_defaults.xml +++ b/core/res/res/values/styles_device_defaults.xml @@ -296,6 +296,10 @@ easier. <style name="TextAppearance.DeviceDefault.Notification.Info" parent="TextAppearance.Material.Notification.Info"> <item name="fontFamily">@string/config_bodyFontFamily</item> </style> + <style name="TextAppearance.DeviceDefault.Notification.Conversation.AppName" + parent="@*android:style/TextAppearance.DeviceDefault.Notification.Title"> + <item name="android:textSize">16sp</item> + </style> <style name="TextAppearance.DeviceDefault.Widget" parent="TextAppearance.Material.Widget"> <item name="fontFamily">@string/config_bodyFontFamily</item> </style> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 431549713f44..88161f6024fc 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1197,9 +1197,9 @@ <java-symbol type="string" name="network_logging_notification_text" /> <java-symbol type="string" name="location_changed_notification_title" /> <java-symbol type="string" name="location_changed_notification_text" /> - <java-symbol type="string" name="personal_apps_suspended_title" /> - <java-symbol type="string" name="personal_apps_suspended_tomorrow_title" /> - <java-symbol type="string" name="personal_apps_suspended_text" /> + <java-symbol type="string" name="personal_apps_suspension_title" /> + <java-symbol type="string" name="personal_apps_suspension_tomorrow_text" /> + <java-symbol type="string" name="personal_apps_suspension_text" /> <java-symbol type="string" name="factory_reset_warning" /> <java-symbol type="string" name="factory_reset_message" /> <java-symbol type="string" name="lockscreen_transport_play_description" /> @@ -1598,6 +1598,8 @@ <java-symbol type="style" name="Theme.DeviceDefault.VoiceInteractionSession" /> <java-symbol type="style" name="Pointer" /> <java-symbol type="style" name="LargePointer" /> + <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Title" /> + <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Info" /> <java-symbol type="attr" name="mediaRouteButtonStyle" /> <java-symbol type="attr" name="externalRouteEnabledDrawable" /> @@ -2822,6 +2824,7 @@ <java-symbol type="string" name="notification_hidden_text" /> <java-symbol type="id" name="app_name_text" /> + <java-symbol type="id" name="app_name_divider" /> <java-symbol type="id" name="header_text" /> <java-symbol type="id" name="header_text_secondary" /> <java-symbol type="id" name="expand_button" /> @@ -3238,7 +3241,9 @@ <java-symbol type="id" name="accessibility_shortcut_target_checkbox" /> <java-symbol type="id" name="accessibility_shortcut_target_icon" /> <java-symbol type="id" name="accessibility_shortcut_target_label" /> - <java-symbol type="id" name="accessibility_shortcut_target_switch_item" /> + <java-symbol type="id" name="accessibility_shortcut_target_status" /> + <java-symbol type="string" name="accessibility_shortcut_menu_item_status_on" /> + <java-symbol type="string" name="accessibility_shortcut_menu_item_status_off" /> <!-- Accessibility Button --> <java-symbol type="layout" name="accessibility_button_chooser" /> @@ -3838,8 +3843,8 @@ <java-symbol type="string" name="accessibility_system_action_quick_settings_label" /> <java-symbol type="string" name="accessibility_system_action_recents_label" /> <java-symbol type="string" name="accessibility_system_action_screenshot_label" /> - <java-symbol type="string" name="accessibility_system_action_toggle_split_screen_label" /> - <java-symbol type="string" name="accessibility_system_action_accessibility_menu_label" /> + <java-symbol type="string" name="accessibility_system_action_accessibility_button_label" /> + <java-symbol type="string" name="accessibility_system_action_accessibility_button_chooser_label" /> <java-symbol type="string" name="accessibility_freeform_caption" /> @@ -3874,7 +3879,10 @@ <java-symbol type="array" name="config_defaultImperceptibleKillingExemptionPkgs" /> <java-symbol type="array" name="config_defaultImperceptibleKillingExemptionProcStates" /> + <java-symbol type="id" name="header_icon_container" /> + <java-symbol type="attr" name="notificationHeaderTextAppearance" /> <java-symbol type="string" name="conversation_single_line_name_display" /> + <java-symbol type="string" name="conversation_single_line_image_placeholder" /> <java-symbol type="string" name="conversation_title_fallback_one_to_one" /> <java-symbol type="string" name="conversation_title_fallback_group_chat" /> <java-symbol type="id" name="conversation_icon" /> @@ -3906,18 +3914,18 @@ <java-symbol type="dimen" name="conversation_badge_side_margin_group_expanded" /> <java-symbol type="dimen" name="conversation_badge_side_margin_group_expanded_face_pile" /> <java-symbol type="dimen" name="conversation_content_start" /> - <java-symbol type="dimen" name="expanded_group_conversation_message_padding_without_app_name" /> + <java-symbol type="dimen" name="expanded_group_conversation_message_padding" /> <java-symbol type="dimen" name="messaging_layout_margin_end" /> <java-symbol type="dimen" name="conversation_header_expanded_padding_end" /> <java-symbol type="dimen" name="conversation_icon_container_top_padding" /> <java-symbol type="dimen" name="conversation_icon_container_top_padding_small_avatar" /> - <java-symbol type="dimen" name="conversation_icon_container_top_padding_no_app_name" /> <java-symbol type="layout" name="notification_template_material_conversation" /> <java-symbol type="dimen" name="button_padding_horizontal_material" /> <java-symbol type="dimen" name="button_inset_horizontal_material" /> <java-symbol type="layout" name="conversation_face_pile_layout" /> <java-symbol type="id" name="conversation_unread_count" /> <java-symbol type="string" name="unread_convo_overflow" /> + <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Conversation.AppName" /> <!-- Intent resolver and share sheet --> <java-symbol type="string" name="resolver_personal_tab" /> @@ -3934,6 +3942,7 @@ <java-symbol type="id" name="resolver_tab_divider" /> <java-symbol type="id" name="resolver_button_bar_divider" /> <java-symbol type="id" name="resolver_empty_state_container" /> + <java-symbol type="id" name="button_bar_container" /> <java-symbol type="string" name="resolver_cant_share_with_work_apps" /> <java-symbol type="string" name="resolver_cant_share_with_work_apps_explanation" /> <java-symbol type="string" name="resolver_cant_share_with_personal_apps" /> diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index cc9c91441e84..67a57aaaa101 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -1470,7 +1470,7 @@ <key-sets> <key-set android:name="A" > <public-key android:name="keyA" - android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="/> + android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMpNthdOxud7roPDZMMomOqXgJJdRfIWpkKEqmC61Mv+Nf6QY3TorEwJeghjSmqj7IbBKrtvfQq4E2XJO1HuspmQO4Ng2gvn+r+6EwNfKc9k55d6s+27SR867jKurBbHNtZMG+tjL1yH4r+tNzcuJCsgyAFqLmxFdcxEwzNvREyRpoYc5RDR0mmTwkMCUhJ6CId1EYEKiCEdNzxv+fWPEb21u+/MWpleGCILs8kglRVb2q/WOzAAvGr4FY5plfaE6N+lr7+UschQ+aMi1+uqewo2o0qPFVmZP5hnwj55K4UMzu/NhhDqQQsX4cSGES1KgHo5MTqRqZjN/I7emw5pFQIDAQAB"/> </key-set> <upgrade-key-set android:name="A"/> </key-sets> diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index c328d720426d..34417e68f11c 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -18,6 +18,8 @@ package android.app.activity; import static android.content.Intent.ACTION_EDIT; import static android.content.Intent.ACTION_VIEW; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.google.common.truth.Truth.assertThat; @@ -31,6 +33,7 @@ import android.app.Activity; import android.app.ActivityThread; import android.app.IApplicationThread; import android.app.PictureInPictureParams; +import android.app.ResourcesManager; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ActivityRelaunchItem; import android.app.servertransaction.ClientTransaction; @@ -38,8 +41,10 @@ import android.app.servertransaction.ClientTransactionItem; import android.app.servertransaction.NewIntentItem; import android.app.servertransaction.ResumeActivityItem; import android.app.servertransaction.StopActivityItem; +import android.content.Context; import android.content.Intent; import android.content.res.Configuration; +import android.hardware.display.DisplayManager; import android.os.IBinder; import android.util.MergedConfiguration; import android.view.Display; @@ -230,9 +235,9 @@ public class ActivityThreadTest { final ActivityThread activityThread = activity.getActivityThread(); final Configuration pendingConfig = new Configuration(); - pendingConfig.orientation = orientation == Configuration.ORIENTATION_LANDSCAPE - ? Configuration.ORIENTATION_PORTRAIT - : Configuration.ORIENTATION_LANDSCAPE; + pendingConfig.orientation = orientation == ORIENTATION_LANDSCAPE + ? ORIENTATION_PORTRAIT + : ORIENTATION_LANDSCAPE; pendingConfig.seq = seq + 2; activityThread.updatePendingActivityConfiguration(activity.getActivityToken(), pendingConfig); @@ -257,7 +262,7 @@ public class ActivityThreadTest { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { final Configuration config = new Configuration(); config.seq = BASE_SEQ; - config.orientation = Configuration.ORIENTATION_PORTRAIT; + config.orientation = ORIENTATION_PORTRAIT; activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config, Display.INVALID_DISPLAY); @@ -307,6 +312,61 @@ public class ActivityThreadTest { } @Test + public void testOrientationChanged_DoesntOverrideVirtualDisplayOrientation() { + final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); + final ActivityThread activityThread = activity.getActivityThread(); + + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + Context appContext = activity.getApplication(); + Configuration originalAppConfig = + new Configuration(appContext.getResources().getConfiguration()); + DisplayManager dm = appContext.getSystemService(DisplayManager.class); + + int virtualDisplayWidth; + int virtualDisplayHeight; + if (originalAppConfig.orientation == ORIENTATION_PORTRAIT) { + virtualDisplayWidth = 100; + virtualDisplayHeight = 200; + } else { + virtualDisplayWidth = 200; + virtualDisplayHeight = 100; + } + Display virtualDisplay = dm.createVirtualDisplay("virtual-display", + virtualDisplayWidth, virtualDisplayHeight, 200, null, 0).getDisplay(); + Context virtualDisplayContext = appContext.createDisplayContext(virtualDisplay); + int originalVirtualDisplayOrientation = virtualDisplayContext.getResources() + .getConfiguration().orientation; + + Configuration newAppConfig = new Configuration(originalAppConfig); + newAppConfig.seq++; + newAppConfig.orientation = newAppConfig.orientation == ORIENTATION_PORTRAIT + ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT; + + activityThread.updatePendingConfiguration(newAppConfig); + activityThread.handleConfigurationChanged(newAppConfig); + + try { + assertEquals("Virtual display orientation should not change when process" + + " configuration orientation changes.", + originalVirtualDisplayOrientation, + virtualDisplayContext.getResources().getConfiguration().orientation); + } finally { + // Make sure to reset the process config to prevent side effects to other + // tests. + Configuration activityThreadConfig = activityThread.getConfiguration(); + activityThreadConfig.seq = originalAppConfig.seq - 1; + + Configuration resourceManagerConfig = ResourcesManager.getInstance() + .getConfiguration(); + resourceManagerConfig.seq = originalAppConfig.seq - 1; + + activityThread.updatePendingConfiguration(originalAppConfig); + activityThread.handleConfigurationChanged(originalAppConfig); + } + }); + } + + @Test public void testResumeAfterNewIntent() { final Activity activity = mActivityTestRule.launchActivity(new Intent()); final ActivityThread activityThread = activity.getActivityThread(); @@ -386,7 +446,7 @@ public class ActivityThreadTest { final int numOfConfig = activity.mNumOfConfigChanges; Configuration config = new Configuration(); - config.orientation = Configuration.ORIENTATION_PORTRAIT; + config.orientation = ORIENTATION_PORTRAIT; config.seq = seq; activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config, Display.INVALID_DISPLAY); @@ -396,7 +456,7 @@ public class ActivityThreadTest { } config = new Configuration(); - config.orientation = Configuration.ORIENTATION_LANDSCAPE; + config.orientation = ORIENTATION_LANDSCAPE; config.seq = seq + 1; activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config, Display.INVALID_DISPLAY); diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java index f0997a68492b..2057a8181147 100644 --- a/core/tests/coretests/src/android/content/ContextTest.java +++ b/core/tests/coretests/src/android/content/ContextTest.java @@ -18,19 +18,26 @@ package android.content; import static android.view.Display.DEFAULT_DISPLAY; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertEquals; import android.app.ActivityThread; import android.hardware.display.DisplayManager; import android.os.UserHandle; -import androidx.test.InstrumentationRegistry; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.Test; import org.junit.runner.RunWith; +/** + * Build/Install/Run: + * atest FrameworksCoreTests:ContextTest + */ @SmallTest @RunWith(AndroidJUnit4.class) public class ContextTest { @@ -43,6 +50,14 @@ public class ContextTest { } @Test + public void testDisplayIdForSystemUiContext() { + final Context systemUiContext = + ActivityThread.currentActivityThread().getSystemUiContext(); + + assertEquals(systemUiContext.getDisplay().getDisplayId(), systemUiContext.getDisplayId()); + } + + @Test public void testDisplayIdForTestContext() { final Context testContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); @@ -89,4 +104,27 @@ public class ContextTest { InstrumentationRegistry.getInstrumentation().getTargetContext(); testContext.startActivityAsUser(new Intent(), new UserHandle(UserHandle.USER_ALL)); } + + @Test + public void testIsUiContext_appContext_returnsFalse() { + final Context appContext = ApplicationProvider.getApplicationContext(); + + assertThat(appContext.isUiContext()).isFalse(); + } + + @Test + public void testIsUiContext_systemContext_returnsTrue() { + final Context systemContext = + ActivityThread.currentActivityThread().getSystemContext(); + + assertThat(systemContext.isUiContext()).isTrue(); + } + + @Test + public void testIsUiContext_systemUiContext_returnsTrue() { + final Context systemUiContext = + ActivityThread.currentActivityThread().getSystemUiContext(); + + assertThat(systemUiContext.isUiContext()).isTrue(); + } } diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index 79cb1f9f85f9..567552f66b35 100644 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -971,8 +971,6 @@ public class PackageManagerTests extends AndroidTestCase { if (retainData) { assertNotNull(info); assertEquals(info.packageName, ip.pkg.packageName); - File file = new File(info.dataDir); - assertTrue(file.exists()); } else { assertNull(info); } @@ -990,7 +988,6 @@ public class PackageManagerTests extends AndroidTestCase { @LargeTest - @Suppress // TODO(b/152007236): un-suppress when we root cause this public void testDeleteNormalInternalRetainData() throws Exception { deleteFromRawResource(0, PackageManager.DELETE_KEEP_DATA); } @@ -2306,7 +2303,6 @@ public class PackageManagerTests extends AndroidTestCase { } } - @Suppress // TODO(b/152007236): un-suppress when we root cause this public void testIsSignedBy() throws Exception { PackageManager pm = getPm(); String mPkgName = mContext.getPackageName(); diff --git a/core/tests/coretests/src/android/content/pm/SigningDetailsTest.java b/core/tests/coretests/src/android/content/pm/SigningDetailsTest.java new file mode 100644 index 000000000000..51af048bcae8 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/SigningDetailsTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content.pm; + +import static android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.content.pm.PackageParser.SigningDetails; +import android.util.ArraySet; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.security.PublicKey; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class SigningDetailsTest { + private static final String FIRST_SIGNATURE = "1234"; + private static final String SECOND_SIGNATURE = "5678"; + private static final String THIRD_SIGNATURE = "9abc"; + + @Test + public void hasAncestor_multipleSignersInLineageWithAncestor_returnsTrue() throws Exception { + SigningDetails twoSignersInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE, THIRD_SIGNATURE); + SigningDetails oneSignerInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE); + + boolean result = twoSignersInLineageDetails.hasAncestor(oneSignerInLineageDetails); + + assertTrue(result); + } + + @Test + public void hasAncestor_oneSignerInLineageAgainstMultipleSignersInLineage_returnsFalse() + throws Exception { + SigningDetails twoSignersInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE, THIRD_SIGNATURE); + SigningDetails oneSignerInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE); + + boolean result = oneSignerInLineageDetails.hasAncestor(twoSignersInLineageDetails); + + assertFalse(result); + } + + @Test + public void hasAncestor_multipleSignersInLineageAgainstSelf_returnsFalse() throws Exception { + SigningDetails twoSignersInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE, THIRD_SIGNATURE); + + boolean result = twoSignersInLineageDetails.hasAncestor(twoSignersInLineageDetails); + + assertFalse(result); + } + + @Test + public void hasAncestor_oneSignerInLineageWithAncestor_returnsTrue() throws Exception { + SigningDetails twoSignersInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE, THIRD_SIGNATURE); + SigningDetails oneSignerDetails = createSigningDetails(FIRST_SIGNATURE); + + boolean result = twoSignersInLineageDetails.hasAncestor(oneSignerDetails); + + assertTrue(result); + } + + @Test + public void hasAncestor_singleSignerAgainstLineage_returnsFalse() throws Exception { + SigningDetails oneSignerDetails = createSigningDetails(FIRST_SIGNATURE); + SigningDetails twoSignersInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE, THIRD_SIGNATURE); + + boolean result = oneSignerDetails.hasAncestor(twoSignersInLineageDetails); + + assertFalse(result); + } + + @Test + public void hasAncestor_multipleSigners_returnsFalse() throws Exception { + SigningDetails twoSignersDetails = createSigningDetails(FIRST_SIGNATURE, SECOND_SIGNATURE); + SigningDetails twoSignersInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE, THIRD_SIGNATURE); + + boolean result1 = twoSignersInLineageDetails.hasAncestor(twoSignersDetails); + boolean result2 = twoSignersDetails.hasAncestor(twoSignersInLineageDetails); + + assertFalse(result1); + assertFalse(result2); + } + + @Test + public void hasAncestor_unknownDetails_returnsFalse() throws Exception { + SigningDetails unknownDetails = SigningDetails.UNKNOWN; + SigningDetails twoSignersInLineageDetails = createSigningDetailsWithLineage(FIRST_SIGNATURE, + SECOND_SIGNATURE, THIRD_SIGNATURE); + + boolean result1 = twoSignersInLineageDetails.hasAncestor(unknownDetails); + boolean result2 = unknownDetails.hasAncestor(twoSignersInLineageDetails); + + assertFalse(result1); + assertFalse(result2); + } + + private SigningDetails createSigningDetailsWithLineage(String... signers) { + Signature[] signingHistory = new Signature[signers.length]; + for (int i = 0; i < signers.length; i++) { + signingHistory[i] = new Signature(signers[i]); + } + Signature[] currentSignature = new Signature[]{signingHistory[signers.length - 1]}; + // TODO: Since the PublicKey ArraySet is not used by any of the tests a generic empty Set + // works for now, but if this is needed in the future consider creating mock PublicKeys that + // can respond as required for the method under test. + ArraySet<PublicKey> publicKeys = new ArraySet<>(); + return new SigningDetails(currentSignature, SIGNING_BLOCK_V3, publicKeys, signingHistory); + } + + private SigningDetails createSigningDetails(String... signers) { + Signature[] currentSignatures = new Signature[signers.length]; + for (int i = 0; i < signers.length; i++) { + currentSignatures[i] = new Signature(signers[i]); + } + // TODO: Similar to above when tests are added that require this it should be updated to use + // mocked PublicKeys. + ArraySet<PublicKey> publicKeys = new ArraySet<>(); + return new SigningDetails(currentSignatures, SIGNING_BLOCK_V3, publicKeys, null); + } +} diff --git a/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java b/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java new file mode 100644 index 000000000000..afbf8db3cd2d --- /dev/null +++ b/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static org.junit.Assert.assertEquals; + +import android.content.res.Configuration; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests for {@link DisplayAdjustmentsTests}. + * + * <p>Build/Install/Run: + * atest FrameworksCoreTests:DisplayAdjustmentsTests + */ +@RunWith(AndroidJUnit4.class) +public class DisplayAdjustmentsTests { + + @Test + public void testDefaultConstructor_hasEmptyConfiguration() { + DisplayAdjustments emptyAdjustments = new DisplayAdjustments(); + + assertEquals(Configuration.EMPTY, emptyAdjustments.getConfiguration()); + } + + @Test + public void testConfigurationConstructor_nullConfigurationBecomesEmpty() { + DisplayAdjustments emptyAdjustments = new DisplayAdjustments((Configuration) null); + + assertEquals(Configuration.EMPTY, emptyAdjustments.getConfiguration()); + } + + @Test + public void testConfigurationConstructor_copiesConfiguration() { + Configuration configuration = new Configuration(); + configuration.colorMode = 1000; + DisplayAdjustments adjustments = new DisplayAdjustments(configuration); + + assertEquals(configuration, adjustments.getConfiguration()); + } + + @Test + public void testDisplayAdjustmentsConstructor_copiesConfiguration() { + Configuration configuration = new Configuration(); + configuration.colorMode = 1000; + DisplayAdjustments oldAdjustments = new DisplayAdjustments(configuration); + + DisplayAdjustments newAdjustments = new DisplayAdjustments(oldAdjustments); + + assertEquals(configuration, newAdjustments.getConfiguration()); + } +} diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java index 03aba25bf9f7..164c372768c0 100644 --- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java @@ -23,36 +23,47 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + import android.content.Context; import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; import android.os.Bundle; import android.platform.test.annotations.Presubmit; -import android.view.SurfaceControl.Transaction; import android.view.WindowManager.BadTokenException; import android.view.WindowManager.LayoutParams; import android.view.inputmethod.EditorInfo; import android.widget.TextView; -import androidx.test.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.FlakyTest; -import androidx.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.Spy; import java.util.ArrayList; +/** + * Test {@link InsetsSourceConsumer} with IME type. + * + * Build/Install/Run: + * atest FrameworksCoreTests:ImeInsetsSourceConsumerTest + */ @Presubmit @FlakyTest(detail = "Promote once confirmed non-flaky") @RunWith(AndroidJUnit4.class) public class ImeInsetsSourceConsumerTest { - Context mContext = InstrumentationRegistry.getTargetContext(); + Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); ImeInsetsSourceConsumer mImeConsumer; - InsetsController mController; + @Spy InsetsController mController; SurfaceControl mLeash; @Before @@ -67,7 +78,8 @@ public class ImeInsetsSourceConsumerTest { } catch (BadTokenException e) { // activity isn't running, we will ignore BadTokenException. } - mController = new InsetsController(viewRootImpl); + mController = Mockito.spy(new InsetsController( + new ViewRootInsetsControllerHost(viewRootImpl))); final Rect rect = new Rect(5, 5, 5, 5); mController.calculateInsets( false, @@ -75,8 +87,7 @@ public class ImeInsetsSourceConsumerTest { new DisplayCutout( Insets.of(10, 10, 10, 10), rect, rect, rect, rect), SOFT_INPUT_ADJUST_RESIZE, 0); - mImeConsumer = new ImeInsetsSourceConsumer( - new InsetsState(), Transaction::new, mController); + mImeConsumer = (ImeInsetsSourceConsumer) mController.getSourceConsumer(ITYPE_IME); }); } @@ -100,6 +111,27 @@ public class ImeInsetsSourceConsumerTest { } @Test + public void testImeRequestedVisibleAwaitingControl() { + // Set null control and then request show. + mController.onControlsChanged(new InsetsSourceControl[] { null }); + + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + // Request IME visible before control is available. + mImeConsumer.onWindowFocusGained(); + mImeConsumer.applyImeVisibility(true /* setVisible */); + + // set control and verify visibility is applied. + InsetsSourceControl control = new InsetsSourceControl(ITYPE_IME, mLeash, new Point()); + mController.onControlsChanged(new InsetsSourceControl[] { control }); + // IME show animation should be triggered when control becomes available. + verify(mController).applyAnimation( + eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(true) /* fromIme */); + verify(mController, never()).applyAnimation( + eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(true) /* fromIme */); + }); + } + + @Test public void testAreEditorsSimilar() { EditorInfo info1 = new EditorInfo(); info1.privateImeOptions = "dummy"; diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index d432dda4a1be..ccf4192ac2f4 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -60,8 +60,8 @@ import android.view.animation.LinearInterpolator; import android.view.test.InsetsModeSession; import android.widget.TextView; -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import com.android.server.testutils.OffsettableClock; import com.android.server.testutils.TestHandler; @@ -113,7 +113,7 @@ public class InsetsControllerTest { .setName("testSurface") .build(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { - Context context = InstrumentationRegistry.getTargetContext(); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); // cannot mock ViewRootImpl since it's final. mViewRoot = new ViewRootImpl(context, context.getDisplayNoVerify()); try { @@ -123,7 +123,8 @@ public class InsetsControllerTest { } mTestClock = new OffsettableClock(); mTestHandler = new TestHandler(null, mTestClock); - mController = new InsetsController(mViewRoot, (controller, type) -> { + mController = new InsetsController(new ViewRootInsetsControllerHost(mViewRoot), + (controller, type) -> { if (type == ITYPE_IME) { return new InsetsSourceConsumer(type, controller.getState(), Transaction::new, controller) { diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java index 754c6791cade..25f94131f820 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java @@ -17,8 +17,8 @@ package android.view; import static android.view.InsetsState.ITYPE_STATUS_BAR; - import static android.view.WindowInsets.Type.statusBars; + import static junit.framework.Assert.assertEquals; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertTrue; @@ -37,8 +37,8 @@ import android.view.WindowManager.BadTokenException; import android.view.WindowManager.LayoutParams; import android.widget.TextView; -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.Before; import org.junit.Test; @@ -89,7 +89,8 @@ public class InsetsSourceConsumerTest { state.addSource(mSpyInsetsSource); mConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, state, - () -> mMockTransaction, new InsetsController(viewRootImpl)); + () -> mMockTransaction, + new InsetsController(new ViewRootInsetsControllerHost(viewRootImpl))); }); instrumentation.waitForIdleSync(); diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java index b3f6fe9e88b9..c61f33e15b18 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.InsetsState.ITYPE_CAPTION_BAR; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; @@ -46,11 +47,13 @@ public class InsetsSourceTest { private InsetsSource mSource = new InsetsSource(ITYPE_NAVIGATION_BAR); private InsetsSource mImeSource = new InsetsSource(ITYPE_IME); + private InsetsSource mCaptionSource = new InsetsSource(ITYPE_CAPTION_BAR); @Before public void setUp() { mSource.setVisible(true); mImeSource.setVisible(true); + mCaptionSource.setVisible(true); } @Test @@ -102,6 +105,17 @@ public class InsetsSourceTest { } @Test + public void testCalculateInsets_caption_resizing() { + mCaptionSource.setFrame(new Rect(0, 0, 100, 100)); + Insets insets = mCaptionSource.calculateInsets(new Rect(0, 0, 200, 200), false); + assertEquals(Insets.of(0, 100, 0, 0), insets); + insets = mCaptionSource.calculateInsets(new Rect(0, 0, 50, 200), false); + assertEquals(Insets.of(0, 100, 0, 0), insets); + insets = mCaptionSource.calculateInsets(new Rect(100, 100, 200, 500), false); + assertEquals(Insets.of(0, 100, 0, 0), insets); + } + + @Test public void testCalculateInsets_invisible() { mSource.setFrame(new Rect(0, 0, 500, 100)); mSource.setVisible(false); diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index 0d497e113537..ecc3b4f072f9 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -40,9 +40,9 @@ import android.platform.test.annotations.Presubmit; import android.view.WindowInsets.Side; import android.view.WindowInsets.Type; -import androidx.test.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.Before; import org.junit.Test; @@ -51,6 +51,12 @@ import org.junit.runner.RunWith; import java.lang.reflect.Field; import java.lang.reflect.Method; +/** + * Tests for {@link ViewRootImpl} + * + * Build/Install/Run: + * atest FrameworksCoreTests:ViewRootImplTest + */ @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) @@ -61,7 +67,7 @@ public class ViewRootImplTest { @Before public void setUp() throws Exception { - mContext = InstrumentationRegistry.getContext(); + mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { mViewRootImpl = new ViewRootImplAccessor( diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java index 45d4b38d82aa..7cde19c30dd4 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java @@ -120,8 +120,10 @@ public class TextViewActivityTest { public void setUp() { mActivity = mActivityRule.getActivity(); mInstrumentation = InstrumentationRegistry.getInstrumentation(); - mActivity.getSystemService(TextClassificationManager.class) - .setTextClassifier(TextClassifier.NO_OP); + TextClassificationManager tcm = mActivity.getSystemService( + TextClassificationManager.class); + tcm.setTextClassifier(TextClassifier.NO_OP); + tcm.setTextClassificationSessionFactory(null); } @Test @@ -1174,6 +1176,53 @@ public class TextViewActivityTest { } @Test + public void testTextClassifierSession() throws Throwable { + useSystemDefaultTextClassifier(); + TextClassificationManager tcm = + mActivity.getSystemService(TextClassificationManager.class); + List<TestableTextClassifier> testableTextClassifiers = new ArrayList<>(); + tcm.setTextClassificationSessionFactory(classificationContext -> { + TestableTextClassifier textClassifier = new TestableTextClassifier(); + testableTextClassifiers.add(textClassifier); + return new TextClassifier() { + private boolean mIsDestroyed = false; + + @Override + public TextSelection suggestSelection(TextSelection.Request request) { + return textClassifier.suggestSelection(request); + } + + @Override + public void destroy() { + mIsDestroyed = true; + } + + @Override + public boolean isDestroyed() { + return mIsDestroyed; + } + }; + }); + + // Long press to trigger selection + onView(withId(R.id.textview)).perform(replaceText("android.com")); + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(0)); + sleepForFloatingToolbarPopup(); + // Click "Copy" to dismiss the selection. + clickFloatingToolbarItem(mActivity.getString(com.android.internal.R.string.copy)); + + // Long press to trigger another selection + onView(withId(R.id.textview)).perform(replaceText("android@android.com")); + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(0)); + sleepForFloatingToolbarPopup(); + + // suggestSelection should be called in two different TextClassifier sessions. + assertEquals(2, testableTextClassifiers.size()); + assertEquals(1, testableTextClassifiers.get(0).getTextSelectionRequests().size()); + assertEquals(1, testableTextClassifiers.get(1).getTextSelectionRequests().size()); + } + + @Test public void testPastePlainText_menuAction() { initializeClipboardWithText(TextStyle.STYLED); @@ -1227,6 +1276,7 @@ public class TextViewActivityTest { private final class TestableTextClassifier implements TextClassifier { final List<SelectionEvent> mSelectionEvents = new ArrayList<>(); + final List<TextSelection.Request> mTextSelectionRequests = new ArrayList<>(); @Override public void onSelectionEvent(SelectionEvent event) { @@ -1235,6 +1285,7 @@ public class TextViewActivityTest { @Override public TextSelection suggestSelection(TextSelection.Request request) { + mTextSelectionRequests.add(request); return new TextSelection.Builder(request.getStartIndex(), request.getEndIndex()) .setEntityType(TextClassifier.TYPE_PHONE, 1) .build(); @@ -1243,5 +1294,9 @@ public class TextViewActivityTest { List<SelectionEvent> getSelectionEvents() { return mSelectionEvents; } + + List<TextSelection.Request> getTextSelectionRequests() { + return mTextSelectionRequests; + } } } diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index c52555b5ed32..80fb35813009 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -34,6 +34,7 @@ import static com.android.internal.app.ChooserListAdapter.SHORTCUT_TARGET_SCORE_ import static com.android.internal.app.ChooserWrapperActivity.sOverrides; import static com.android.internal.app.MatcherUtils.first; +import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static org.hamcrest.CoreMatchers.is; @@ -41,6 +42,8 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; @@ -55,6 +58,8 @@ import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; @@ -302,7 +307,7 @@ public class ChooserActivityTest { waitForIdle(); UsageStatsManager usm = activity.getUsageStatsManager(); verify(sOverrides.resolverListController, times(1)) - .topK(Mockito.any(List.class), Mockito.anyInt()); + .topK(any(List.class), anyInt()); assertThat(activity.getIsSelected(), is(false)); sOverrides.onSafelyStartCallback = targetInfo -> { return true; @@ -312,7 +317,7 @@ public class ChooserActivityTest { .perform(click()); waitForIdle(); verify(sOverrides.resolverListController, times(1)) - .updateChooserCounts(Mockito.anyString(), Mockito.anyInt(), Mockito.anyString()); + .updateChooserCounts(Mockito.anyString(), anyInt(), Mockito.anyString()); verify(sOverrides.resolverListController, times(1)) .updateModel(toChoose.activityInfo.getComponentName()); assertThat(activity.getIsSelected(), is(true)); @@ -1750,6 +1755,83 @@ public class ChooserActivityTest { assertThat(chosen[0], is(personalResolvedComponentInfos.get(1).getResolveInfoAt(0))); } + @Test + public void testOneInitialIntent_noAutolaunch() { + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTest(1); + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + Intent chooserIntent = createChooserIntent(new Intent[] {new Intent("action.fake")}); + ResolveInfo[] chosen = new ResolveInfo[1]; + sOverrides.onSafelyStartCallback = targetInfo -> { + chosen[0] = targetInfo.getResolveInfo(); + return true; + }; + sOverrides.packageManager = mock(PackageManager.class); + ResolveInfo ri = createFakeResolveInfo(); + when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(ri); + waitForIdle(); + + ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent); + waitForIdle(); + + assertNull(chosen[0]); + assertThat(activity.getPersonalListAdapter().getCallerTargetCount(), is(1)); + } + + @Test + public void testWorkTab_withInitialIntents_workTabDoesNotIncludePersonalInitialIntents() { + // enable the work tab feature flag + ResolverActivity.ENABLE_TABBED_VIEW = true; + markWorkProfileUserAvailable(); + int workProfileTargets = 1; + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10); + List<ResolvedComponentInfo> workResolvedComponentInfos = + createResolvedComponentsForTest(workProfileTargets); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); + Intent[] initialIntents = { + new Intent("action.fake1"), + new Intent("action.fake2") + }; + Intent chooserIntent = createChooserIntent(initialIntents); + sOverrides.packageManager = mock(PackageManager.class); + when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())) + .thenReturn(createFakeResolveInfo()); + waitForIdle(); + + ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent); + waitForIdle(); + + assertThat(activity.getPersonalListAdapter().getCallerTargetCount(), is(2)); + assertThat(activity.getWorkListAdapter().getCallerTargetCount(), is(0)); + } + + private Intent createChooserIntent(Intent[] initialIntents) { + Intent chooserIntent = new Intent(); + chooserIntent.setAction(Intent.ACTION_CHOOSER); + chooserIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending"); + chooserIntent.putExtra(Intent.EXTRA_TITLE, "some title"); + chooserIntent.putExtra(Intent.EXTRA_INTENT, createSendTextIntent()); + chooserIntent.setType("text/plain"); + if (initialIntents != null) { + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, initialIntents); + } + return chooserIntent; + } + + private ResolveInfo createFakeResolveInfo() { + ResolveInfo ri = new ResolveInfo(); + ri.activityInfo = new ActivityInfo(); + ri.activityInfo.name = "FakeActivityName"; + ri.activityInfo.packageName = "fake.package.name"; + ri.activityInfo.applicationInfo = new ApplicationInfo(); + ri.activityInfo.applicationInfo.packageName = "fake.package.name"; + return ri; + } + private Intent createSendTextIntent() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java index 5b83f952b745..071b2259e1f0 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -58,6 +58,18 @@ public class ChooserWrapperActivity extends ChooserActivity { return multiProfilePagerAdapter; } + @Override + public ChooserListAdapter createChooserListAdapter(Context context, List<Intent> payloadIntents, + Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, + boolean useLayoutForBrowsables, ResolverListController resolverListController) { + PackageManager packageManager = + sOverrides.packageManager == null ? context.getPackageManager() + : sOverrides.packageManager; + return new ChooserListAdapter(context, payloadIntents, initialIntents, rList, + filterLastUsed, resolverListController, useLayoutForBrowsables, + this, this, packageManager); + } + ChooserListAdapter getAdapter() { return mChooserMultiProfilePagerAdapter.getActiveListAdapter(); } @@ -217,6 +229,7 @@ public class ChooserWrapperActivity extends ChooserActivity { public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; + public PackageManager packageManager; public void reset() { onSafelyStartCallback = null; @@ -235,6 +248,7 @@ public class ChooserWrapperActivity extends ChooserActivity { workProfileUserHandle = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; + packageManager = null; multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { @Override public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, diff --git a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java index 3e40466e4b64..02870a53773e 100644 --- a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java +++ b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java @@ -19,20 +19,26 @@ package com.android.internal.policy; import static android.view.Display.DEFAULT_DISPLAY; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import android.app.Activity; +import android.app.EmptyActivity; import android.content.Context; import android.hardware.display.DisplayManagerGlobal; import android.platform.test.annotations.Presubmit; import android.view.Display; import android.view.DisplayAdjustments; import android.view.DisplayInfo; +import android.view.WindowManager; +import android.view.WindowManagerImpl; -import androidx.test.InstrumentationRegistry; +import androidx.test.core.app.ApplicationProvider; import androidx.test.filters.SmallTest; +import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; - import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -46,17 +52,22 @@ public final class DecorContextTest { private Context mContext; private static final int EXTERNAL_DISPLAY = DEFAULT_DISPLAY + 1; + @Rule + public ActivityTestRule<EmptyActivity> mActivityRule = + new ActivityTestRule<>(EmptyActivity.class); + @Before - public void setUp() throws Exception { - mContext = InstrumentationRegistry.getContext(); + public void setUp() { + mContext = ApplicationProvider.getApplicationContext(); } @Test public void testDecorContextWithDefaultDisplay() { Display defaultDisplay = new Display(DisplayManagerGlobal.getInstance(), DEFAULT_DISPLAY, new DisplayInfo(), DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - DecorContext context = new DecorContext(mContext.getApplicationContext(), - mContext.createDisplayContext(defaultDisplay)); + final Context defaultDisplayContext = mContext.createDisplayContext(defaultDisplay); + final PhoneWindow window = new PhoneWindow(defaultDisplayContext); + DecorContext context = new DecorContext(mContext.getApplicationContext(), window); assertDecorContextDisplay(DEFAULT_DISPLAY, context); } @@ -65,8 +76,9 @@ public final class DecorContextTest { public void testDecorContextWithExternalDisplay() { Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY, new DisplayInfo(), DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - DecorContext context = new DecorContext(mContext.getApplicationContext(), - mContext.createDisplayContext(display)); + final Context defaultDisplayContext = mContext.createDisplayContext(display); + final PhoneWindow window = new PhoneWindow(defaultDisplayContext); + DecorContext context = new DecorContext(mContext.getApplicationContext(), window); assertDecorContextDisplay(EXTERNAL_DISPLAY, context); } @@ -76,4 +88,29 @@ public final class DecorContextTest { Display associatedDisplay = decorContext.getDisplay(); assertEquals(expectedDisplayId, associatedDisplay.getDisplayId()); } + + @Test + public void testGetWindowManagerFromVisualDecorContext() throws Throwable { + mActivityRule.runOnUiThread(() -> { + Activity activity = mActivityRule.getActivity(); + final DecorContext decorContext = new DecorContext(mContext.getApplicationContext(), + (PhoneWindow) activity.getWindow()); + WindowManagerImpl actualWm = (WindowManagerImpl) + decorContext.getSystemService(WindowManager.class); + WindowManagerImpl expectedWm = (WindowManagerImpl) + activity.getSystemService(WindowManager.class); + // Verify that window manager is from activity not application context. + assertEquals(expectedWm.mContext, actualWm.mContext); + }); + } + + @Test + public void testIsUiContextFromVisualDecorContext() throws Throwable { + mActivityRule.runOnUiThread(() -> { + Activity activity = mActivityRule.getActivity(); + final DecorContext decorContext = new DecorContext(mContext.getApplicationContext(), + (PhoneWindow) activity.getWindow()); + assertTrue(decorContext.isUiContext()); + }); + } } diff --git a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java index 2141b815fb3b..7cd2f3b4c2ab 100644 --- a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java +++ b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java @@ -354,6 +354,15 @@ public class HdmiAudioSystemClientTest { @Override public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) { } + + @Override + public void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) { + } + + @Override + public boolean isHdmiCecVolumeControlEnabled() { + return true; + } } } diff --git a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java new file mode 100644 index 000000000000..8e4f38ef15d3 --- /dev/null +++ b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.os.Bundle; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.widget.InlinePresentationStyleUtils; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class InlinePresentationStyleUtilsTest { + @Test + public void testBundleEquals_empty() { + Bundle bundle1 = new Bundle(); + Bundle bundle2 = new Bundle(); + + assertTrue(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + + bundle1 = Bundle.EMPTY; + assertTrue(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + + bundle2 = Bundle.EMPTY; + assertTrue(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + } + + @Test + public void testBundleEquals_oneIsEmpty() { + Bundle bundle1 = Bundle.EMPTY; + Bundle bundle2 = new Bundle(); + bundle2.putString("KEY", "value"); + assertFalse(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + } + + @Test + public void testBundleEquals_nestedBundle_equal() { + Bundle bundle1 = new Bundle(); + Bundle bundle11 = new Bundle(); + bundle11.putString("KEY", "VALUE"); + bundle1.putBundle("KEY_B", bundle11); + + Bundle bundle2 = new Bundle(); + Bundle bundle21 = new Bundle(); + bundle21.putString("KEY", "VALUE"); + bundle2.putBundle("KEY_B", bundle21); + + assertTrue(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + } + + @Test + public void testBundleEquals_nestedBundle_unequal() { + Bundle bundle1 = new Bundle(); + Bundle bundle11 = new Bundle(); + bundle11.putString("KEY", "VALUE"); + bundle1.putBundle("KEY_B", bundle11); + + Bundle bundle2 = new Bundle(); + bundle2.putBundle("KEY_B", new Bundle()); + + assertFalse(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + } + + @Test + public void testBundleEquals_sameKeyDifferentType() { + Bundle bundle1 = new Bundle(); + bundle1.putBundle("KEY_B", new Bundle()); + + Bundle bundle2 = new Bundle(); + bundle2.putInt("KEY_B", 12); + + assertFalse(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + } + + @Test + public void testBundleEquals_primitiveValue_equal() { + Bundle bundle1 = new Bundle(); + bundle1.putInt("KEY", 11); + Bundle bundle2 = new Bundle(); + bundle2.putInt("KEY", 11); + assertTrue(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + } + + @Test + public void testBundleEquals_primitiveValue_unequal() { + Bundle bundle1 = new Bundle(); + bundle1.putInt("KEY", 11); + Bundle bundle2 = new Bundle(); + bundle2.putInt("KEY", 22); + assertFalse(InlinePresentationStyleUtils.bundleEquals(bundle1, bundle2)); + } +} diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java index 8c6a9371d53b..4c7e960eb0a4 100644 --- a/graphics/java/android/graphics/BLASTBufferQueue.java +++ b/graphics/java/android/graphics/BLASTBufferQueue.java @@ -26,15 +26,17 @@ public final class BLASTBufferQueue { // Note: This field is accessed by native code. private long mNativeObject; // BLASTBufferQueue* - private static native long nativeCreate(long surfaceControl, long width, long height); + private static native long nativeCreate(long surfaceControl, long width, long height, + boolean tripleBufferingEnabled); private static native void nativeDestroy(long ptr); private static native Surface nativeGetSurface(long ptr); private static native void nativeSetNextTransaction(long ptr, long transactionPtr); private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height); /** Create a new connection with the surface flinger. */ - public BLASTBufferQueue(SurfaceControl sc, int width, int height) { - mNativeObject = nativeCreate(sc.mNativeObject, width, height); + public BLASTBufferQueue(SurfaceControl sc, int width, int height, + boolean tripleBufferingEnabled) { + mNativeObject = nativeCreate(sc.mNativeObject, width, height, tripleBufferingEnabled); } public void destroy() { @@ -64,4 +66,3 @@ public final class BLASTBufferQueue { } } } - diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 83432c362672..97b448aa8ff0 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -270,7 +270,7 @@ public final class ImageDecoder implements AutoCloseable { public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException { AssetFileDescriptor assetFd = null; try { - if (mUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { + if (ContentResolver.SCHEME_CONTENT.equals(mUri.getScheme())) { assetFd = mResolver.openTypedAssetFileDescriptor(mUri, "image/*", null); } else { diff --git a/identity/java/android/security/identity/AccessControlProfileId.java b/identity/java/android/security/identity/AccessControlProfileId.java index 3d5945065ad7..6caac0a8a065 100644 --- a/identity/java/android/security/identity/AccessControlProfileId.java +++ b/identity/java/android/security/identity/AccessControlProfileId.java @@ -25,6 +25,8 @@ public class AccessControlProfileId { /** * Constructs a new object holding a numerical identifier. * + * <p>The identifier must be a non-negative number and less than 32. + * * @param id the identifier. */ public AccessControlProfileId(int id) { diff --git a/identity/java/android/security/identity/IdentityCredentialStore.java b/identity/java/android/security/identity/IdentityCredentialStore.java index 4f834d2b87b5..3843d9279900 100644 --- a/identity/java/android/security/identity/IdentityCredentialStore.java +++ b/identity/java/android/security/identity/IdentityCredentialStore.java @@ -46,7 +46,7 @@ import java.lang.annotation.RetentionPolicy; * access control profile IDs. Names are strings and values are typed and can be any * value supported by <a href="http://cbor.io/">CBOR</a>.</li> * - * <li>A set of access control profiles, each with a profile ID and a specification + * <li>A set of access control profiles (up to 32), each with a profile ID and a specification * of the conditions which satisfy the profile's requirements.</li> * * <li>An asymmetric key pair which is used to authenticate the credential to the Issuing diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 2d00010f51ee..da52cfef6bc6 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -686,6 +686,23 @@ public class AudioSystem String effectName = effects.length == 0 ? "None" : effects[0].name; if (cb != null) { + ArrayList<AudioPatch> audioPatches = new ArrayList<>(); + if (AudioManager.listAudioPatches(audioPatches) == AudioManager.SUCCESS) { + boolean patchFound = false; + int patchHandle = recordingFormat[6]; + for (AudioPatch patch : audioPatches) { + if (patch.id() == patchHandle) { + patchFound = true; + break; + } + } + if (!patchFound) { + // The cached audio patches in AudioManager is not up-to-date. + // Reset audio port generation to ensure callback side can + // get up-to-date audio port information. + AudioManager.resetAudioPortGeneration(); + } + } // TODO receive package name from native cb.onRecordingConfigurationChanged(event, riid, uid, session, source, portId, silenced, recordingFormat, clientEffects, effects, activeSource, ""); diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java index fb95e98ebf47..72162c44ec29 100644 --- a/media/java/android/media/MediaRoute2ProviderService.java +++ b/media/java/android/media/MediaRoute2ProviderService.java @@ -519,6 +519,7 @@ public abstract class MediaRoute2ProviderService extends Service { requestCreateSession)); } + //TODO: Ignore requests with unknown session ID. @Override public void selectRoute(long requestId, String sessionId, String routeId) { if (!checkCallerisSystem()) { diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 2c65cc4440a4..7d14ef5542cc 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -604,7 +604,8 @@ public final class MediaRouter2 { RoutingController oldController = getCurrentController(); if (!oldController.releaseInternal( - /* shouldReleaseSession= */ true, /* shouldNotifyStop= */ false)) { + /* shouldReleaseSession= */ matchingRequest != null, + /* shouldNotifyStop= */ false)) { // Could not release the controller since it was just released by other thread. oldController = getSystemController(); } diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java index 3b570b60ff24..5d61dd06c792 100644 --- a/media/java/android/media/MediaRouter2Manager.java +++ b/media/java/android/media/MediaRouter2Manager.java @@ -314,7 +314,6 @@ public final class MediaRouter2Manager { //TODO: Ignore unknown route. if (sessionInfo.getTransferableRoutes().contains(route.getId())) { - //TODO: callbacks must be called after this. transferToRoute(sessionInfo, route); return; } @@ -340,7 +339,6 @@ public final class MediaRouter2Manager { } catch (RemoteException ex) { Log.e(TAG, "Unable to select media route", ex); } - releaseSession(sessionInfo); } } @@ -489,6 +487,7 @@ public final class MediaRouter2Manager { notifyTransferFailed(matchingRequest.mOldSessionInfo, requestedRoute); return; } + releaseSession(matchingRequest.mOldSessionInfo); notifyTransferred(matchingRequest.mOldSessionInfo, sessionInfo); } diff --git a/media/java/android/media/tv/tuner/filter/MediaEvent.java b/media/java/android/media/tv/tuner/filter/MediaEvent.java index 247c1c47560a..af63070027a2 100644 --- a/media/java/android/media/tv/tuner/filter/MediaEvent.java +++ b/media/java/android/media/tv/tuner/filter/MediaEvent.java @@ -28,14 +28,19 @@ import android.media.MediaCodec.LinearBlock; */ @SystemApi public class MediaEvent extends FilterEvent { - private native int nativeGetAudioHandle(); + private long mNativeContext; + private final Object mLock = new Object(); + + private native Long nativeGetAudioHandle(); + private native LinearBlock nativeGetLinearBlock(); + private native void nativeFinalize(); private final int mStreamId; private final boolean mIsPtsPresent; private final long mPts; private final long mDataLength; private final long mOffset; - private final LinearBlock mLinearBlock; + private LinearBlock mLinearBlock; private final boolean mIsSecureMemory; private final long mDataId; private final int mMpuSequenceNumber; @@ -103,7 +108,12 @@ public class MediaEvent extends FilterEvent { */ @Nullable public LinearBlock getLinearBlock() { - return mLinearBlock; + synchronized (mLock) { + if (mLinearBlock == null) { + mLinearBlock = nativeGetLinearBlock(); + } + return mLinearBlock; + } } /** @@ -163,4 +173,15 @@ public class MediaEvent extends FilterEvent { public AudioDescriptor getExtraMetaData() { return mExtraMetaData; } + + + /** + * Finalize the MediaEvent object. + * @hide + */ + @Override + protected void finalize() { + nativeFinalize(); + mNativeContext = 0; + } } diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index ab311c0e245a..805831442756 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -21,8 +21,7 @@ #include "android_media_tv_Tuner.h" #include "android_runtime/AndroidRuntime.h" -#include <C2BlockInternal.h> -#include <C2HandleIonInternal.h> +#include <android-base/logging.h> #include <android/hardware/tv/tuner/1.0/ITuner.h> #include <media/stagefright/foundation/ADebug.h> #include <nativehelper/JNIHelp.h> @@ -145,6 +144,7 @@ struct fields_t { jfieldID descramblerContext; jfieldID dvrRecorderContext; jfieldID dvrPlaybackContext; + jfieldID mediaEventContext; jmethodID frontendInitID; jmethodID filterInitID; jmethodID timeFilterInitID; @@ -169,6 +169,12 @@ static fields_t gFields; static int IP_V4_LENGTH = 4; static int IP_V6_LENGTH = 16; +void DestroyCallback(const C2Buffer * /* buf */, void *arg) { + android::sp<android::MediaEvent> event = (android::MediaEvent *)arg; + event->mAvHandleRefCnt--; + event->finalize(); +} + namespace android { /////////////// LnbCallback /////////////////////// LnbCallback::LnbCallback(jobject lnbObj, LnbId id) : mId(id) { @@ -280,17 +286,69 @@ MQ& Dvr::getDvrMQ() { return *mDvrMQ; } -/////////////// FilterCallback /////////////////////// -//TODO: implement filter callback -jobject FilterCallback::handleToLinearBlock(const native_handle_t* handle, uint32_t size) { - ALOGD("FilterCallback::handleToLinearBlock"); - C2HandleIon* ion = new C2HandleIon(handle->data[0], size); - std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(ion); +/////////////// C2DataIdInfo /////////////////////// + +C2DataIdInfo::C2DataIdInfo(uint32_t index, uint64_t value) : C2Param(kParamSize, index) { + CHECK(isGlobal()); + CHECK_EQ(C2Param::INFO, kind()); + DummyInfo info{value}; + memcpy(this + 1, static_cast<C2Param *>(&info) + 1, kParamSize - sizeof(C2Param)); +} + +/////////////// MediaEvent /////////////////////// + +MediaEvent::MediaEvent(sp<IFilter> iFilter, hidl_handle avHandle, + uint64_t dataId, uint64_t dataLength, jobject obj) : mIFilter(iFilter), + mDataId(dataId), mDataLength(dataLength), mBuffer(nullptr), + mDataIdRefCnt(0), mAvHandleRefCnt(0), mIonHandle(nullptr) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + mMediaEventObj = env->NewWeakGlobalRef(obj); + mAvHandle = native_handle_clone(avHandle.getNativeHandle()); +} + +MediaEvent::~MediaEvent() { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + env->DeleteWeakGlobalRef(mMediaEventObj); + mMediaEventObj = NULL; + native_handle_delete(mAvHandle); + if (mIonHandle != NULL) { + delete mIonHandle; + } + if (mC2Buffer != NULL) { + mC2Buffer->unregisterOnDestroyNotify(&DestroyCallback, this); + } +} + +void MediaEvent::finalize() { + if (mAvHandleRefCnt == 0) { + mIFilter->releaseAvHandle(hidl_handle(mAvHandle), mDataIdRefCnt == 0 ? mDataId : 0); + native_handle_close(mAvHandle); + } +} + +jobject MediaEvent::getLinearBlock() { + ALOGD("MediaEvent::getLinearBlock"); + if (mAvHandle == NULL) { + return NULL; + } + if (mLinearBlockObj != NULL) { + return mLinearBlockObj; + } + mIonHandle = new C2HandleIon(mAvHandle->data[0], mDataLength); + std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(mIonHandle); JNIEnv *env = AndroidRuntime::getJNIEnv(); std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock}; context->mBlock = block; - + mC2Buffer = context->toC2Buffer(0, mDataLength); + if (mAvHandle->numInts > 0) { + // use first int in the native_handle as the index + int index = mAvHandle->data[mAvHandle->numFds]; + std::shared_ptr<C2Param> c2param = std::make_shared<C2DataIdInfo>(index, mDataId); + std::shared_ptr<C2Info> info(std::static_pointer_cast<C2Info>(c2param)); + mC2Buffer->setInfo(info); + } + mC2Buffer->registerOnDestroyNotify(&DestroyCallback, this); jobject linearBlock = env->NewObject( env->FindClass("android/media/MediaCodec$LinearBlock"), @@ -300,9 +358,18 @@ jobject FilterCallback::handleToLinearBlock(const native_handle_t* handle, uint3 gFields.linearBlockSetInternalStateID, (jlong)context.release(), true); - return linearBlock; + mLinearBlockObj = env->NewWeakGlobalRef(linearBlock); + mAvHandleRefCnt++; + return mLinearBlockObj; } +uint64_t MediaEvent::getAudioHandle() { + mDataIdRefCnt++; + return mDataId; +} + +/////////////// FilterCallback /////////////////////// + jobjectArray FilterCallback::getSectionEvent( jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -333,6 +400,7 @@ jobjectArray FilterCallback::getMediaEvent( "<init>", "(IZJJJLandroid/media/MediaCodec$LinearBlock;" "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V"); + jfieldID eventContext = env->GetFieldID(eventClazz, "mNativeContext", "J"); for (int i = 0; i < events.size(); i++) { auto event = events[i]; @@ -358,12 +426,6 @@ jobjectArray FilterCallback::getMediaEvent( } jlong dataLength = static_cast<jlong>(mediaEvent.dataLength); - const native_handle_t* h = NULL; - jobject block = NULL; - if (mediaEvent.avMemory != NULL) { - h = mediaEvent.avMemory.getNativeHandle(); - block = handleToLinearBlock(h, dataLength); - } jint streamId = static_cast<jint>(mediaEvent.streamId); jboolean isPtsPresent = static_cast<jboolean>(mediaEvent.isPtsPresent); @@ -376,8 +438,18 @@ jobjectArray FilterCallback::getMediaEvent( jobject obj = env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, dataLength, - offset, block, isSecureMemory, avDataId, mpuSequenceNumber, isPesPrivateData, + offset, NULL, isSecureMemory, avDataId, mpuSequenceNumber, isPesPrivateData, audioDescriptor); + + if (mediaEvent.avMemory.getNativeHandle() != NULL || mediaEvent.avDataId != 0) { + sp<MediaEvent> mediaEventSp = + new MediaEvent(mIFilter, mediaEvent.avMemory, + mediaEvent.avDataId, dataLength, obj); + mediaEventSp->mAvHandleRefCnt++; + env->SetLongField(obj, eventContext, (jlong) mediaEventSp.get()); + mediaEventSp->incStrong(obj); + } + env->SetObjectArrayElement(arr, i, obj); } return arr; @@ -594,10 +666,10 @@ Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) { return Void(); } -void FilterCallback::setFilter(const jobject filter) { +void FilterCallback::setFilter(const sp<Filter> filter) { ALOGD("FilterCallback::setFilter"); - JNIEnv *env = AndroidRuntime::getJNIEnv(); - mFilter = env->NewWeakGlobalRef(filter); + mFilter = filter->mFilterObj; + mIFilter = filter->mFilterSp; } FilterCallback::~FilterCallback() { @@ -1431,7 +1503,7 @@ jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { filterSp->incStrong(filterObj); env->SetLongField(filterObj, gFields.filterContext, (jlong)filterSp.get()); - callback->setFilter(filterObj); + callback->setFilter(filterSp); return filterObj; } @@ -2390,6 +2462,9 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) { gFields.onDvrPlaybackStatusID = env->GetMethodID(dvrPlaybackClazz, "onPlaybackStatusChanged", "(I)V"); + jclass mediaEventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); + gFields.mediaEventContext = env->GetFieldID(mediaEventClazz, "mNativeContext", "J"); + jclass linearBlockClazz = env->FindClass("android/media/MediaCodec$LinearBlock"); gFields.linearBlockInitID = env->GetMethodID(linearBlockClazz, "<init>", "()V"); gFields.linearBlockSetInternalStateID = @@ -3507,6 +3582,52 @@ static jlong android_media_tv_Tuner_write_dvr_to_array( return copyData(env, dvrSp->mDvrMQ, dvrSp->mDvrMQEventFlag, buffer, offset, size); } +static sp<MediaEvent> getMediaEventSp(JNIEnv *env, jobject mediaEventObj) { + return (MediaEvent *)env->GetLongField(mediaEventObj, gFields.mediaEventContext); +} + +static jobject android_media_tv_Tuner_media_event_get_linear_block( + JNIEnv* env, jobject mediaEventObj) { + sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj); + if (mediaEventSp == NULL) { + ALOGD("Failed get MediaEvent"); + return NULL; + } + + return mediaEventSp->getLinearBlock(); +} + +static jobject android_media_tv_Tuner_media_event_get_audio_handle( + JNIEnv* env, jobject mediaEventObj) { + sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj); + if (mediaEventSp == NULL) { + ALOGD("Failed get MediaEvent"); + return NULL; + } + + android::Mutex::Autolock autoLock(mediaEventSp->mLock); + uint64_t audioHandle = mediaEventSp->getAudioHandle(); + jclass longClazz = env->FindClass("java/lang/Long"); + jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V"); + + jobject longObj = env->NewObject(longClazz, longInit, static_cast<jlong>(audioHandle)); + return longObj; +} + +static void android_media_tv_Tuner_media_event_finalize(JNIEnv* env, jobject mediaEventObj) { + sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj); + if (mediaEventSp == NULL) { + ALOGD("Failed get MediaEvent"); + return; + } + + android::Mutex::Autolock autoLock(mediaEventSp->mLock); + mediaEventSp->mAvHandleRefCnt--; + mediaEventSp->finalize(); + + mediaEventSp->decStrong(mediaEventObj); +} + static const JNINativeMethod gTunerMethods[] = { { "nativeInit", "()V", (void *)android_media_tv_Tuner_native_init }, { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup }, @@ -3629,6 +3750,15 @@ static const JNINativeMethod gLnbMethods[] = { { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_lnb }, }; +static const JNINativeMethod gMediaEventMethods[] = { + { "nativeGetLinearBlock", "()Landroid/media/MediaCodec$LinearBlock;", + (void *)android_media_tv_Tuner_media_event_get_linear_block }, + { "nativeGetAudioHandle", "()Ljava/lang/Long;", + (void *)android_media_tv_Tuner_media_event_get_audio_handle }, + { "nativeFinalize", "()V", + (void *)android_media_tv_Tuner_media_event_finalize }, +}; + static bool register_android_media_tv_Tuner(JNIEnv *env) { if (AndroidRuntime::registerNativeMethods( env, "android/media/tv/tuner/Tuner", gTunerMethods, NELEM(gTunerMethods)) != JNI_OK) { @@ -3677,6 +3807,13 @@ static bool register_android_media_tv_Tuner(JNIEnv *env) { ALOGE("Failed to register lnb native methods"); return false; } + if (AndroidRuntime::registerNativeMethods( + env, "android/media/tv/tuner/filter/MediaEvent", + gMediaEventMethods, + NELEM(gMediaEventMethods)) != JNI_OK) { + ALOGE("Failed to register MediaEvent native methods"); + return false; + } return true; } diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index 3da78acb2f90..c469a3ad8b76 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -18,10 +18,14 @@ #define _ANDROID_MEDIA_TV_TUNER_H_ #include <android/hardware/tv/tuner/1.0/ITuner.h> +#include <C2BlockInternal.h> +#include <C2HandleIonInternal.h> +#include <C2ParamDef.h> #include <fmq/MessageQueue.h> #include <fstream> #include <string> #include <unordered_map> +#include <utils/Mutex.h> #include <utils/RefBase.h> #include "jni.h" @@ -30,6 +34,7 @@ using ::android::hardware::EventFlag; using ::android::hardware::MQDescriptorSync; using ::android::hardware::MessageQueue; using ::android::hardware::Return; +using ::android::hardware::hidl_handle; using ::android::hardware::hidl_vec; using ::android::hardware::kSynchronizedReadWrite; using ::android::hardware::tv::tuner::V1_0::DemuxFilterEvent; @@ -106,15 +111,48 @@ struct Dvr : public RefBase { int mFd; }; +struct MediaEvent : public RefBase { + MediaEvent(sp<IFilter> iFilter, hidl_handle avHandle, uint64_t dataId, + uint64_t dataLength, jobject obj); + ~MediaEvent(); + jobject getLinearBlock(); + uint64_t getAudioHandle(); + void finalize(); + + sp<IFilter> mIFilter; + native_handle_t* mAvHandle; + uint64_t mDataId; + uint64_t mDataLength; + uint8_t* mBuffer; + android::Mutex mLock; + int mDataIdRefCnt; + int mAvHandleRefCnt; + jweak mMediaEventObj; + jweak mLinearBlockObj; + C2HandleIon* mIonHandle; + std::shared_ptr<C2Buffer> mC2Buffer; +}; + +struct Filter : public RefBase { + Filter(sp<IFilter> sp, jobject obj); + ~Filter(); + int close(); + sp<IFilter> getIFilter(); + sp<IFilter> mFilterSp; + std::unique_ptr<MQ> mFilterMQ; + EventFlag* mFilterMQEventFlag; + jweak mFilterObj; +}; + struct FilterCallback : public IFilterCallback { ~FilterCallback(); virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent); virtual Return<void> onFilterStatus(const DemuxFilterStatus status); - void setFilter(const jobject filter); - jobject handleToLinearBlock(const native_handle_t* handle, uint32_t size); + void setFilter(const sp<Filter> filter); private: jweak mFilter; + sp<IFilter> mIFilter; jobjectArray getSectionEvent( jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); jobjectArray getMediaEvent( @@ -144,17 +182,6 @@ struct FrontendCallback : public IFrontendCallback { FrontendId mId; }; -struct Filter : public RefBase { - Filter(sp<IFilter> sp, jobject obj); - ~Filter(); - int close(); - sp<IFilter> getIFilter(); - sp<IFilter> mFilterSp; - std::unique_ptr<MQ> mFilterMQ; - EventFlag* mFilterMQEventFlag; - jweak mFilterObj; -}; - struct TimeFilter : public RefBase { TimeFilter(sp<ITimeFilter> sp, jweak obj); ~TimeFilter(); @@ -219,6 +246,14 @@ private: static jobject getIsdbtFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps); }; +class C2DataIdInfo : public C2Param { +public: + C2DataIdInfo(uint32_t index, uint64_t value); +private: + typedef C2GlobalParam<C2Info, C2Int64Value, 0> DummyInfo; + static const size_t kParamSize = sizeof(DummyInfo); +}; + } // namespace android #endif // _ANDROID_MEDIA_TV_TUNER_H_ diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp index 809e81b13a45..e3152d6349aa 100644 --- a/media/jni/soundpool/Stream.cpp +++ b/media/jni/soundpool/Stream.cpp @@ -330,7 +330,9 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID, AudioTrack::TRANSFER_DEFAULT, nullptr /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mStreamManager->getAttributes()); - + // Set caller name so it can be logged in destructor. + // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL + newTrack->setCallerName("soundpool"); oldTrack = mAudioTrack; status = newTrack->initCheck(); if (status != NO_ERROR) { diff --git a/media/packages/BluetoothMidiService/Android.bp b/media/packages/BluetoothMidiService/Android.bp index 77e6a14e1f00..48fc329276bd 100644 --- a/media/packages/BluetoothMidiService/Android.bp +++ b/media/packages/BluetoothMidiService/Android.bp @@ -20,7 +20,6 @@ android_library { "src/**/*.java", ], platform_apis: true, - plugins: ["java_api_finder"], manifest: "AndroidManifestBase.xml", } diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types index c1f8b3f0e195..05a2e92ca080 100644 --- a/mime/java-res/android.mime.types +++ b/mime/java-res/android.mime.types @@ -72,7 +72,7 @@ ?application/x-x509-server-cert crt ?application/x-x509-user-cert crt -?audio/3gpp 3gpp 3ga +?audio/3gpp 3ga 3gpp ?audio/aac-adts aac ?audio/ac3 ac3 a52 ?audio/amr amr diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml index d0916b518c92..a8c70989253e 100644 --- a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml @@ -33,7 +33,6 @@ android:gravity="top" android:paddingTop="30dp" android:layout_weight="1" - android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> <com.android.systemui.car.navigationbar.CarNavigationButton diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml index de5a15068a5c..9e6dd113eeba 100644 --- a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml +++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml @@ -33,7 +33,6 @@ android:gravity="top" android:paddingTop="30dp" android:layout_weight="1" - android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> <com.android.systemui.car.navigationbar.CarNavigationButton diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml index d386ce3300e6..fd75570e759c 100644 --- a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml @@ -36,7 +36,6 @@ android:gravity="top" android:paddingTop="30dp" android:layout_weight="1" - android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> <com.android.systemui.car.navigationbar.CarNavigationButton diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml index de5a15068a5c..9e6dd113eeba 100644 --- a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml +++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml @@ -33,7 +33,6 @@ android:gravity="top" android:paddingTop="30dp" android:layout_weight="1" - android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> <com.android.systemui.car.navigationbar.CarNavigationButton diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml index 050db3218a1d..67066d7c426f 100644 --- a/packages/CarSystemUI/res/values/config.xml +++ b/packages/CarSystemUI/res/values/config.xml @@ -92,35 +92,28 @@ <item>com.android.vending</item> </string-array> - <!-- SystemUI Services: The classes of the stuff to start. --> - <string-array name="config_systemUIServiceComponents" translatable="false"> - <item>com.android.systemui.util.NotificationChannels</item> - <item>com.android.systemui.keyguard.KeyguardViewMediator</item> -<!-- <item>com.android.systemui.recents.Recents</item>--> -<!-- <item>com.android.systemui.volume.VolumeUI</item>--> -<!-- <item>com.android.systemui.stackdivider.Divider</item>--> -<!-- <item>com.android.systemui.statusbar.phone.StatusBar</item>--> - <item>com.android.systemui.usb.StorageNotification</item> - <item>com.android.systemui.power.PowerUI</item> - <item>com.android.systemui.media.RingtonePlayer</item> -<!-- <item>com.android.systemui.keyboard.KeyboardUI</item>--> -<!-- <item>com.android.systemui.pip.PipUI</item>--> -<!-- <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>--> - <item>@string/config_systemUIVendorServiceComponent</item> - <item>com.android.systemui.util.leak.GarbageMonitor$Service</item> -<!-- <item>com.android.systemui.LatencyTester</item>--> -<!-- <item>com.android.systemui.globalactions.GlobalActionsComponent</item>--> - <item>com.android.systemui.ScreenDecorations</item> - <item>com.android.systemui.biometrics.AuthController</item> -<!-- <item>com.android.systemui.SliceBroadcastRelayHandler</item>--> - <item>com.android.systemui.SizeCompatModeActivityController</item> -<!-- <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>--> - <item>com.android.systemui.theme.ThemeOverlayController</item> - <item>com.android.systemui.toast.ToastUI</item> + <!-- The list of components to exclude from config_systemUIServiceComponents. --> + <string-array name="config_systemUIServiceComponentsExclude" translatable="false"> + <item>com.android.systemui.recents.Recents</item> + <item>com.android.systemui.volume.VolumeUI</item> + <item>com.android.systemui.stackdivider.Divider</item> + <item>com.android.systemui.statusbar.phone.StatusBar</item> + <item>com.android.systemui.keyboard.KeyboardUI</item> + <item>com.android.systemui.pip.PipUI</item> + <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item> + <item>com.android.systemui.LatencyTester</item> + <item>com.android.systemui.globalactions.GlobalActionsComponent</item> + <item>com.android.systemui.SliceBroadcastRelayHandler</item> + <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item> + <item>com.android.systemui.accessibility.WindowMagnification</item> + <item>com.android.systemui.accessibility.SystemActions</item> + </string-array> + + <!-- The list of components to append to config_systemUIServiceComponents. --> + <string-array name="config_systemUIServiceComponentsInclude" translatable="false"> <item>com.android.systemui.car.navigationbar.CarNavigationBar</item> <item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item> <item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item> <item>com.android.systemui.car.volume.VolumeUI</item> - <item>com.android.systemui.car.sideloaded.SideLoadedAppController</item> </string-array> </resources> diff --git a/packages/CarSystemUI/res/values/strings.xml b/packages/CarSystemUI/res/values/strings.xml index 881e746d633d..9fae4b3e2b46 100644 --- a/packages/CarSystemUI/res/values/strings.xml +++ b/packages/CarSystemUI/res/values/strings.xml @@ -16,15 +16,15 @@ --> <resources> - <!-- String to represent lowest setting of an HVAC system [CHAR LIMIT=5]--> + <!-- String to represent lowest setting of an HVAC system [CHAR LIMIT=10]--> <string name="hvac_min_text">Min</string> - <!-- String to represent largest setting of an HVAC system [CHAR LIMIT=5]--> + <!-- String to represent largest setting of an HVAC system [CHAR LIMIT=10]--> <string name="hvac_max_text">Max</string> <!-- Text for voice recognition toast. [CHAR LIMIT=60] --> <string name="voice_recognition_toast">Voice recognition now handled by connected Bluetooth device</string> - <!-- Name of Guest Profile. [CHAR LIMIT=30] --> + <!-- Name of Guest Profile. [CHAR LIMIT=35] --> <string name="car_guest">Guest</string> - <!-- Title for button that starts a guest session. [CHAR LIMIT=30] --> + <!-- Title for button that starts a guest session. [CHAR LIMIT=35] --> <string name="start_guest_session">Guest</string> <!-- Title for button that adds a new user. [CHAR LIMIT=30] --> <string name="car_add_user">Add User</string> diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java index 2bd5fe228f41..1a1b93b33caf 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java @@ -17,9 +17,13 @@ package com.android.systemui; import android.content.Context; +import android.content.res.Resources; import com.android.systemui.dagger.SystemUIRootComponent; +import java.util.HashSet; +import java.util.Set; + /** * Class factory to provide car specific SystemUI components. */ @@ -31,4 +35,26 @@ public class CarSystemUIFactory extends SystemUIFactory { .contextHolder(new ContextHolder(context)) .build(); } + + @Override + public String[] getSystemUIServiceComponents(Resources resources) { + Set<String> names = new HashSet<>(); + + for (String s : super.getSystemUIServiceComponents(resources)) { + names.add(s); + } + + for (String s : resources.getStringArray(R.array.config_systemUIServiceComponentsExclude)) { + names.remove(s); + } + + for (String s : resources.getStringArray(R.array.config_systemUIServiceComponentsInclude)) { + names.add(s); + } + + String[] finalNames = new String[names.size()]; + names.toArray(finalNames); + + return finalNames; + } } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java index 6a0a31bbeef9..baa6ac945a8a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java @@ -51,6 +51,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import javax.inject.Inject; import javax.inject.Singleton; +import dagger.Lazy; + /** * Automotive implementation of the {@link KeyguardViewController}. It controls the Keyguard View * that is mounted to the SystemUIOverlayWindow. @@ -66,9 +68,10 @@ public class CarKeyguardViewController extends OverlayViewController implements private final CarServiceProvider mCarServiceProvider; private final KeyguardStateController mKeyguardStateController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy; private final LockPatternUtils mLockPatternUtils; private final FalsingManager mFalsingManager; - private final KeyguardBypassController mKeyguardBypassController; + private final Lazy<KeyguardBypassController> mKeyguardBypassControllerLazy; private final DismissCallbackRegistry mDismissCallbackRegistry; private final ViewMediatorCallback mViewMediatorCallback; private final CarNavigationBarController mCarNavigationBarController; @@ -109,14 +112,14 @@ public class CarKeyguardViewController extends OverlayViewController implements OverlayViewGlobalStateController overlayViewGlobalStateController, KeyguardStateController keyguardStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, - BiometricUnlockController biometricUnlockController, + Lazy<BiometricUnlockController> biometricUnlockControllerLazy, ViewMediatorCallback viewMediatorCallback, CarNavigationBarController carNavigationBarController, /* The params below are only used to reuse KeyguardBouncer */ LockPatternUtils lockPatternUtils, DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager, - KeyguardBypassController keyguardBypassController) { + Lazy<KeyguardBypassController> keyguardBypassControllerLazy) { super(R.id.keyguard_stub, overlayViewGlobalStateController); @@ -125,14 +128,14 @@ public class CarKeyguardViewController extends OverlayViewController implements mCarServiceProvider = carServiceProvider; mKeyguardStateController = keyguardStateController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; + mBiometricUnlockControllerLazy = biometricUnlockControllerLazy; mLockPatternUtils = lockPatternUtils; mFalsingManager = falsingManager; - mKeyguardBypassController = keyguardBypassController; + mKeyguardBypassControllerLazy = keyguardBypassControllerLazy; mDismissCallbackRegistry = dismissCallbackRegistry; mViewMediatorCallback = viewMediatorCallback; mCarNavigationBarController = carNavigationBarController; - biometricUnlockController.setKeyguardViewController(this); registerUserSwitchedListener(); } @@ -142,12 +145,15 @@ public class CarKeyguardViewController extends OverlayViewController implements mViewMediatorCallback, mLockPatternUtils, getLayout().findViewById(R.id.keyguard_container), mDismissCallbackRegistry, mExpansionCallback, mKeyguardStateController, mFalsingManager, - mKeyguardBypassController); + mKeyguardBypassControllerLazy.get()); + mBiometricUnlockControllerLazy.get().setKeyguardViewController(this); } @Override public void notifyKeyguardAuthenticated(boolean strongAuth) { - mBouncer.notifyKeyguardAuthenticated(strongAuth); + if (mBouncer != null) { + mBouncer.notifyKeyguardAuthenticated(strongAuth); + } } @Override @@ -200,11 +206,15 @@ public class CarKeyguardViewController extends OverlayViewController implements @Override public void onFinishedGoingToSleep() { - mBouncer.onScreenTurnedOff(); + if (mBouncer != null) { + mBouncer.onScreenTurnedOff(); + } } @Override public void onCancelClicked() { + if (!mShowing) return; + getOverlayViewGlobalStateController().setWindowFocusable(/* focusable= */ false); getOverlayViewGlobalStateController().setWindowNeedsInput(/* needsInput= */ false); @@ -224,6 +234,8 @@ public class CarKeyguardViewController extends OverlayViewController implements @Override public void startPreHideAnimation(Runnable finishRunnable) { + if (!mShowing) return; + mBouncer.startPreHideAnimation(finishRunnable); } @@ -256,12 +268,12 @@ public class CarKeyguardViewController extends OverlayViewController implements @Override public boolean isBouncerShowing() { - return mBouncer.isShowing(); + return mBouncer != null && mBouncer.isShowing(); } @Override public boolean bouncerIsOrWillBeShowing() { - return mBouncer.isShowing() || mBouncer.inTransit(); + return mBouncer != null && (mBouncer.isShowing() || mBouncer.inTransit()); } @Override diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java index 2b5cab783916..fcc8c8cddeb1 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java @@ -19,7 +19,6 @@ package com.android.systemui.car.navigationbar; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.containsType; -import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; @@ -28,11 +27,9 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.PixelFormat; import android.inputmethodservice.InputMethodService; -import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; -import android.os.ServiceManager; import android.view.Display; import android.view.Gravity; import android.view.View; @@ -47,6 +44,7 @@ import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.car.CarDeviceProvisionedListener; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.statusbar.AutoHideUiElement; @@ -76,15 +74,16 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks private final AutoHideController mAutoHideController; private final ButtonSelectionStateListener mButtonSelectionStateListener; private final Handler mMainHandler; + private final Handler mBgHandler; + private final IStatusBarService mBarService; private final Lazy<KeyguardStateController> mKeyguardStateControllerLazy; private final ButtonSelectionStateController mButtonSelectionStateController; - private final PhoneStatusBarPolicy mIconPolicy; - private final StatusBarIconController mIconController; + private final Lazy<PhoneStatusBarPolicy> mIconPolicyLazy; + private final Lazy<StatusBarIconController> mIconControllerLazy; private final int mDisplayId; private StatusBarSignalPolicy mSignalPolicy; - private IStatusBarService mBarService; private ActivityManagerWrapper mActivityManagerWrapper; // If the nav bar should be hidden when the soft keyboard is visible. @@ -121,10 +120,12 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks AutoHideController autoHideController, ButtonSelectionStateListener buttonSelectionStateListener, @Main Handler mainHandler, + @Background Handler bgHandler, + IStatusBarService barService, Lazy<KeyguardStateController> keyguardStateControllerLazy, ButtonSelectionStateController buttonSelectionStateController, - PhoneStatusBarPolicy iconPolicy, - StatusBarIconController iconController + Lazy<PhoneStatusBarPolicy> iconPolicyLazy, + Lazy<StatusBarIconController> iconControllerLazy ) { super(context); mResources = resources; @@ -135,10 +136,12 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks mAutoHideController = autoHideController; mButtonSelectionStateListener = buttonSelectionStateListener; mMainHandler = mainHandler; + mBgHandler = bgHandler; + mBarService = barService; mKeyguardStateControllerLazy = keyguardStateControllerLazy; mButtonSelectionStateController = buttonSelectionStateController; - mIconPolicy = iconPolicy; - mIconController = iconController; + mIconPolicyLazy = iconPolicyLazy; + mIconControllerLazy = iconControllerLazy; mDisplayId = context.getDisplayId(); } @@ -150,10 +153,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard); mBottomNavBarVisible = false; - // Get bar service. - mBarService = IStatusBarService.Stub.asInterface( - ServiceManager.getService(Context.STATUS_BAR_SERVICE)); - // Connect into the status bar manager service mCommandQueue.addCallback(this); @@ -233,11 +232,15 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks mActivityManagerWrapper = ActivityManagerWrapper.getInstance(); mActivityManagerWrapper.registerTaskStackListener(mButtonSelectionStateListener); - mCarNavigationBarController.connectToHvac(); + mBgHandler.post(() -> mCarNavigationBarController.connectToHvac()); // Lastly, call to the icon policy to install/update all the icons. - mIconPolicy.init(); - mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconController); + // Must be called on the main thread due to the use of observeForever() in + // mIconPolicy.init(). + mMainHandler.post(() -> { + mIconPolicyLazy.get().init(); + mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconControllerLazy.get()); + }); } private void restartNavBarsIfNecessary() { @@ -349,33 +352,38 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height, - WindowManager.LayoutParams.TYPE_STATUS_BAR, + WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH - | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); - lp.token = new Binder(); - lp.gravity = Gravity.TOP; - lp.setFitInsetsTypes(0 /* types */); lp.setTitle("TopCarNavigationBar"); - lp.packageName = mContext.getPackageName(); - lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR}; + lp.setFitInsetsTypes(0); + lp.windowAnimations = 0; + lp.gravity = Gravity.TOP; mWindowManager.addView(mTopNavigationBarWindow, lp); } if (mBottomNavigationBarWindow != null && !mBottomNavBarVisible) { mBottomNavBarVisible = true; + int height = mResources.getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height); WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, + ViewGroup.LayoutParams.MATCH_PARENT, + height, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.setTitle("BottomCarNavigationBar"); + lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; lp.windowAnimations = 0; + lp.gravity = Gravity.BOTTOM; mWindowManager.addView(mBottomNavigationBarWindow, lp); } @@ -392,11 +400,10 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks PixelFormat.TRANSLUCENT); leftlp.setTitle("LeftCarNavigationBar"); leftlp.windowAnimations = 0; - leftlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR; leftlp.gravity = Gravity.LEFT; - leftlp.setFitInsetsTypes(0 /* types */); mWindowManager.addView(mLeftNavigationBarWindow, leftlp); } + if (mRightNavigationBarWindow != null) { int width = mResources.getDimensionPixelSize( R.dimen.car_right_navigation_bar_width); @@ -410,9 +417,7 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks PixelFormat.TRANSLUCENT); rightlp.setTitle("RightCarNavigationBar"); rightlp.windowAnimations = 0; - rightlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR; rightlp.gravity = Gravity.RIGHT; - rightlp.setFitInsetsTypes(0 /* types */); mWindowManager.addView(mRightNavigationBarWindow, rightlp); } } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java index 55c11530fc37..9e194fb49d3a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java @@ -20,7 +20,6 @@ import android.content.Context; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.systemui.R; @@ -160,8 +159,12 @@ public class CarNavigationBarController { } /** Gets the top navigation bar with the appropriate listeners set. */ - @NonNull + @Nullable public CarNavigationBarView getTopBar(boolean isSetUp) { + if (!mShowTop) { + return null; + } + mTopView = mNavigationBarViewFactory.getTopBar(isSetUp); setupBar(mTopView, mTopBarTouchListener, mNotificationsShadeController); return mTopView; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java index 46a720b88419..20fc1bcd6013 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java @@ -16,10 +16,14 @@ package com.android.systemui.car.navigationbar; +import static android.view.WindowInsets.Type.systemBars; + import android.content.Context; +import android.graphics.Insets; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; +import android.view.WindowInsets; import android.widget.LinearLayout; import com.android.systemui.Dependency; @@ -44,7 +48,6 @@ public class CarNavigationBarView extends LinearLayout { // used to wire in open/close gestures for notifications private OnTouchListener mStatusBarWindowTouchListener; - public CarNavigationBarView(Context context, AttributeSet attrs) { super(context, attrs); mConsumeTouchWhenPanelOpen = getResources().getBoolean( @@ -75,6 +78,30 @@ public class CarNavigationBarView extends LinearLayout { setClickable(true); } + @Override + public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) { + applyMargins(windowInsets.getInsets(systemBars())); + return windowInsets; + } + + private void applyMargins(Insets insets) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + View child = getChildAt(i); + if (child.getLayoutParams() instanceof LayoutParams) { + LayoutParams lp = (LayoutParams) child.getLayoutParams(); + if (lp.rightMargin != insets.right || lp.leftMargin != insets.left + || lp.topMargin != insets.top || lp.bottomMargin != insets.bottom) { + lp.rightMargin = insets.right; + lp.leftMargin = insets.left; + lp.topMargin = insets.top; + lp.bottomMargin = insets.bottom; + child.requestLayout(); + } + } + } + } + // Used to forward touch events even if the touch was initiated from a child component @Override public boolean onInterceptTouchEvent(MotionEvent ev) { diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java index 09a462185dac..8d3eb4c2bbee 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java @@ -53,7 +53,7 @@ public class TopNotificationPanelViewMediator extends NotificationPanelViewMedia @Override public void registerListeners() { super.registerListeners(); - getCarNavigationBarController().registerBottomBarTouchListener( + getCarNavigationBarController().registerTopBarTouchListener( getNotificationPanelViewController().getDragOpenTouchListener()); } } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java index 3f88422ba2e5..8cca0ed308b2 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java @@ -17,6 +17,7 @@ package com.android.systemui.car.window; import android.content.Context; +import android.util.Log; import com.android.systemui.R; import com.android.systemui.SystemUI; @@ -35,7 +36,7 @@ import javax.inject.Singleton; */ @Singleton public class SystemUIOverlayWindowManager extends SystemUI { - private static final String TAG = "SystemUIOverlayWindowManager"; + private static final String TAG = "SystemUIOverlayWM"; private final Map<Class<?>, Provider<OverlayViewMediator>> mContentMediatorCreators; private final OverlayViewGlobalStateController mOverlayViewGlobalStateController; @@ -59,6 +60,7 @@ public class SystemUIOverlayWindowManager extends SystemUI { private void startServices(String[] services) { for (String clsName : services) { + long ti = System.currentTimeMillis(); try { OverlayViewMediator obj = resolveContentMediator(clsName); if (obj == null) { @@ -73,6 +75,12 @@ public class SystemUIOverlayWindowManager extends SystemUI { | InvocationTargetException ex) { throw new RuntimeException(ex); } + + // Warn if initialization of component takes too long + ti = System.currentTimeMillis() - ti; + if (ti > 200) { + Log.w(TAG, "Initialization of " + clsName + " took " + ti + " ms"); + } } } diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java index d40b1af67ca6..a2192af14758 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java @@ -54,6 +54,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import dagger.Lazy; + @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class CarKeyguardViewControllerTest extends SysuiTestCase { @@ -88,13 +90,13 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase { mOverlayViewGlobalStateController, mock(KeyguardStateController.class), mock(KeyguardUpdateMonitor.class), - mock(BiometricUnlockController.class), + () -> mock(BiometricUnlockController.class), mock(ViewMediatorCallback.class), mock(CarNavigationBarController.class), mock(LockPatternUtils.class), mock(DismissCallbackRegistry.class), mock(FalsingManager.class), - mock(KeyguardBypassController.class) + () -> mock(KeyguardBypassController.class) ); } @@ -186,17 +188,17 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase { OverlayViewGlobalStateController overlayViewGlobalStateController, KeyguardStateController keyguardStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, - BiometricUnlockController biometricUnlockController, + Lazy<BiometricUnlockController> biometricUnlockControllerLazy, ViewMediatorCallback viewMediatorCallback, CarNavigationBarController carNavigationBarController, LockPatternUtils lockPatternUtils, DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager, - KeyguardBypassController keyguardBypassController) { + Lazy<KeyguardBypassController> keyguardBypassControllerLazy) { super(context, mainHandler, carServiceProvider, overlayViewGlobalStateController, - keyguardStateController, keyguardUpdateMonitor, biometricUnlockController, + keyguardStateController, keyguardUpdateMonitor, biometricUnlockControllerLazy, viewMediatorCallback, carNavigationBarController, lockPatternUtils, - dismissCallbackRegistry, falsingManager, keyguardBypassController); + dismissCallbackRegistry, falsingManager, keyguardBypassControllerLazy); } @Override diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java index 6620e9d506ab..c555f64825d8 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java @@ -33,6 +33,7 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; +import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; @@ -57,6 +58,7 @@ public class CarNavigationBarTest extends SysuiTestCase { private CarNavigationBar mCarNavigationBar; private TestableResources mTestableResources; private Handler mHandler; + private Handler mBackgroundHandler; @Mock private CarNavigationBarController mCarNavigationBarController; @@ -69,6 +71,8 @@ public class CarNavigationBarTest extends SysuiTestCase { @Mock private ButtonSelectionStateListener mButtonSelectionStateListener; @Mock + private IStatusBarService mBarService; + @Mock private KeyguardStateController mKeyguardStateController; @Mock private ButtonSelectionStateController mButtonSelectionStateController; @@ -82,11 +86,12 @@ public class CarNavigationBarTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mTestableResources = mContext.getOrCreateTestableResources(); mHandler = Handler.getMain(); + mBackgroundHandler = Handler.createAsync(TestableLooper.get(this).getLooper()); mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(), mCarNavigationBarController, mWindowManager, mDeviceProvisionedController, new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener, - mHandler, () -> mKeyguardStateController, mButtonSelectionStateController, - mIconPolicy, mIconController); + mHandler, mBackgroundHandler, mBarService, () -> mKeyguardStateController, + mButtonSelectionStateController, () -> mIconPolicy, () -> mIconController); } @Test @@ -103,7 +108,7 @@ public class CarNavigationBarTest extends SysuiTestCase { verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture()); deviceProvisionedCallbackCaptor.getValue().onUserSwitched(); - waitForIdleSync(mHandler); + waitForIdleSync(mBackgroundHandler); verify(mButtonSelectionStateListener).onTaskStackChanged(); } @@ -123,7 +128,7 @@ public class CarNavigationBarTest extends SysuiTestCase { verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture()); deviceProvisionedCallbackCaptor.getValue().onUserSwitched(); - waitForIdleSync(mHandler); + waitForIdleSync(mBackgroundHandler); verify(mCarNavigationBarController).showAllKeyguardButtons(false); } @@ -142,12 +147,12 @@ public class CarNavigationBarTest extends SysuiTestCase { when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false); verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture()); deviceProvisionedCallbackCaptor.getValue().onUserSwitched(); - waitForIdleSync(mHandler); + waitForIdleSync(mBackgroundHandler); when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true); when(mKeyguardStateController.isShowing()).thenReturn(false); deviceProvisionedCallbackCaptor.getValue().onUserSetupChanged(); - waitForIdleSync(mHandler); + waitForIdleSync(mBackgroundHandler); verify(mCarNavigationBarController).hideAllKeyguardButtons(true); } diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk Binary files differindex 54ee0d07df34..7f5c94891473 100644 --- a/packages/CtsShim/apk/arm/CtsShim.apk +++ b/packages/CtsShim/apk/arm/CtsShim.apk diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk Binary files differindex ca34af947986..9dc2352e7d51 100644 --- a/packages/CtsShim/apk/arm/CtsShimPriv.apk +++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk Binary files differindex 54ee0d07df34..7f5c94891473 100644 --- a/packages/CtsShim/apk/x86/CtsShim.apk +++ b/packages/CtsShim/apk/x86/CtsShim.apk diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk Binary files differindex edbb1519eff6..388e939c097c 100644 --- a/packages/CtsShim/apk/x86/CtsShimPriv.apk +++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk diff --git a/packages/CtsShim/build/Android.bp b/packages/CtsShim/build/Android.bp index be790106f42d..d41c6728559b 100644 --- a/packages/CtsShim/build/Android.bp +++ b/packages/CtsShim/build/Android.bp @@ -76,6 +76,7 @@ android_app { "com.android.apex.cts.shim.v2_no_hashtree", "com.android.apex.cts.shim.v2_legacy", "com.android.apex.cts.shim.v2_sdk_target_p", + "com.android.apex.cts.shim.v2_unsigned_payload", "com.android.apex.cts.shim.v3", ], } @@ -148,6 +149,7 @@ android_app { "com.android.apex.cts.shim.v2_no_hashtree", "com.android.apex.cts.shim.v2_legacy", "com.android.apex.cts.shim.v2_sdk_target_p", + "com.android.apex.cts.shim.v2_unsigned_payload", "com.android.apex.cts.shim.v3", ], } diff --git a/packages/CtsShim/build/jni/Android.bp b/packages/CtsShim/build/jni/Android.bp index 7a5b07e61e9d..44775828e535 100644 --- a/packages/CtsShim/build/jni/Android.bp +++ b/packages/CtsShim/build/jni/Android.bp @@ -25,6 +25,7 @@ cc_library_shared { "com.android.apex.cts.shim.v2_no_hashtree", "com.android.apex.cts.shim.v2_legacy", "com.android.apex.cts.shim.v2_sdk_target_p", + "com.android.apex.cts.shim.v2_unsigned_payload", "com.android.apex.cts.shim.v3", ], } diff --git a/packages/DynamicSystemInstallationService/res/values-af/strings.xml b/packages/DynamicSystemInstallationService/res/values-af/strings.xml new file mode 100644 index 000000000000..1829d342e9c5 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-af/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Voer asseblief jou wagwoord in en gaan voort na Dinamiese Steselopdaterings"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamiese stelsel is gereed. Herbegin jou toestel om dit te begin gebruik."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installeer tans"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Kon nie installeer nie"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Kon nie prent bekragtig nie. Staak installering."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Laat loop tans \'n dinamiese stelsel. Herbegin om die oorspronklike Android-weergawe te gebruik."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Kanselleer"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Gooi weg"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Herbegin"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Herbegin"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Het dinamiese stelsel weggegooi"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Kan nie dinamiese stelsel herbegin of laai nie"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-am/strings.xml b/packages/DynamicSystemInstallationService/res/values-am/strings.xml new file mode 100644 index 000000000000..7fcc40de38d2 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-am/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"እባክዎ የእርስዎን የይለፍ ቃል ያስገቡ እና ወደ የተለዋዋጭ ሥርዓት ዝማኔዎች ይቀጥሉ"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"የተለዋዋጭ ሥርዓት ዝግጁ ነው። እሱን መጠቀም ለመጀመር የእርስዎን መሣሪያ ዳግም ያስጀምሩ።"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ጭነት በሂደት ላይ ነው"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"መጫን አልተሳካም"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"የምስል ማረጋገጫ አልተሳካም። ጭነትን አጨናግፍ።"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"የተለዋዋጭ ሥርዓትን አሁን ላይ በማስሄድ ላይ ኦርጂናሉን የAndroid ስሪት በመጠቀም ዳግም ያስጀምሩ።"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ይቅር"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"አስወግድ"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ዳግም ጀምር"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ዳግም ጀምር"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"የተጣለ ተለዋዋጭ ሥርዓት"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ዳግም ማስጀመር አይቻልም ወይም ተለዋዋጭ ሥርዓትን ይስቀሉ"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ar/strings.xml b/packages/DynamicSystemInstallationService/res/values-ar/strings.xml new file mode 100644 index 000000000000..be705c37ef1d --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ar/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"يُرجى إدخال كلمة مرور والمتابعة إلى \"تحديثات النظام الديناميكية\""</string> + <string name="notification_install_completed" msgid="6252047868415172643">"النظام الديناميكي جاهز. لبدء استخدامه، يجب إعادة تشغيل الجهاز."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"التثبيت قيد التقدّم."</string> + <string name="notification_install_failed" msgid="4066039210317521404">"تعذّر التثبيت."</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"تعذّر التحقّق من الصورة. يجب إلغاء التثبيت."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"يتم الآن تشغيل نظام ديناميكي. يجب إعادة التشغيل لاستخدام الإصدار الأصلي لنظام Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"إلغاء"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"تجاهل"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"إعادة التشغيل"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"إعادة التشغيل"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"تم تجاهل النظام الديناميكي."</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"لا يمكن إعادة التشغيل أو تحميل النظام الديناميكي."</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-as/strings.xml b/packages/DynamicSystemInstallationService/res/values-as/strings.xml new file mode 100644 index 000000000000..14eead9f9753 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-as/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"অনুগ্ৰহ কৰি আপোনাৰ পাছৱৰ্ডটো দিয়ক আৰু ডায়নামিক ছিষ্টেম আপডে\'টসমূহলৈ অব্যাহত ৰাখক"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ডায়নামিক ছিষ্টেমটো সাজু। এইটো ব্যৱহাৰ কৰা আৰম্ভ কৰিবলৈ আপোনাৰ ডিভাইচটো ৰিষ্টাৰ্ট কৰক।"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ইনষ্টল চলি আছে"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ইনষ্টল কৰিব পৰা নগ’ল"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"প্ৰতিচ্ছবিখন সত্যাপন কৰিব পৰা নগ’ল। ইনষ্টলেশ্বন বাতিল কৰক।"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"বৰ্তমান এটা ডায়নামিক ছিষ্টেম চলি আছে। মূল Android সংস্কৰণটো ব্যৱহাৰ কৰিবলৈ ৰিষ্টাৰ্ট কৰক।"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"বাতিল কৰক"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"বাতিল কৰক"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ৰিষ্টাৰ্ট কৰক"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ৰিষ্টাৰ্ট কৰক"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"বাতিল কৰা ডায়নামিক ছিষ্টেম"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ডায়নামিক ছিষ্টেম ৰিষ্টার্ট অথবা ল\'ড কৰিব নোৱাৰি"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-az/strings.xml b/packages/DynamicSystemInstallationService/res/values-az/strings.xml new file mode 100644 index 000000000000..d1f0a4b78ebb --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-az/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Parolunuzu daxil edin və Dinamik Sistem Güncəlləməsinə keçin"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamik sistem hazırdır. İstifadəyə başlamaq üçün cihazınızı yenidən başladın."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Quraşdırılır"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Quraşdırılmadı"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Şəkil təsdiqlənmədi. Quraşdırmanı dayandırın."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Hazırda dinamik sistem icra olunur. Orijinal Android versiyasından istifadə etmək üçün yenidən başladın."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Ləğv edin"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"İmtina edin"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Yenidən başladın"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Yenidən başladın"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamik sistemdən imtina edildi"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamik sistemi yenidən başlatmaq və ya yükləmək mümkün deyil"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000000..ea23a28bc9e5 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Unesite lozinku i nastavite do dinamičnih ažuriranja sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamični sistem je spreman. Da biste počeli da ga koristite, restartujte uređaj."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalira se"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Instaliranje nije uspelo"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Validacija slike nije uspela. Otkažite instalaciju."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Trenutno je pokrenut dinamični sistem. Restartujte da biste koristili originalnu verziju Android-a."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Otkaži"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Odbaci"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restartuj"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartuj"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je odbačen"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Restartovanje ili učitavanje dinamičnog sistema nije uspelo"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-be/strings.xml b/packages/DynamicSystemInstallationService/res/values-be/strings.xml new file mode 100644 index 000000000000..7eef297be292 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-be/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Увядзіце пароль і перайдзіце ў Дынамічныя абнаўленні сістэмы"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Дынамічная сістэма гатовая. Каб пачаць выкарыстоўваць яе, перазапусціце прыладу."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Ідзе ўсталёўка"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Збой усталёўкі"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Збой пры праверцы відарыса. Усталёўка спынена."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Цяпер запушчана дынамічная сістэма. Перазапусціце, каб скарыстаць арыгінальную версію Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Скасаваць"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Адхіліць"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Перазапусціць"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Перазапусціць"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Дынамічная сістэма адхілена"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не ўдалося перазапусціць або загрузіць дынамічную сістэму"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-bg/strings.xml b/packages/DynamicSystemInstallationService/res/values-bg/strings.xml new file mode 100644 index 000000000000..9176676c0618 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-bg/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Моля, въведете паролата си и продължете към функцията за динамични актуализации на системата"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамичната система е готова. Рестартирайте устройството си, за да я използвате."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Инсталиране – в ход"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Инсталирането не бе успешно"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Проверката на изображението не бе успешна. Прекратяване на инсталирането."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Понастоящем се изпълнява динамична система. Рестартирайте, за да използвате оригиналната версия на Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Отказ"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Отхвърляне"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Рестартиране"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартиране"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамичната система е отхвърлена"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамичната система не може да се рестартира или зареди"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-bn/strings.xml b/packages/DynamicSystemInstallationService/res/values-bn/strings.xml new file mode 100644 index 000000000000..38ef64935fb4 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-bn/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"আপনার পাসওয়ার্ড লিখে ডায়নামিক সিস্টেম আপডেট করা চালিয়ে যান"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ডায়নামিক সিস্টেম রেডি হয়ে গেছে। সেটি ব্যবহার করা শুরু করতে আপনার ডিভাইস রিস্টার্ট করুন।"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ইনস্টল করা হচ্ছে"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ইনস্টল করা যায়নি"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ছবি যাচাই করা যায়নি। ইনস্টলেশন বন্ধ করুন।"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"বর্তমানে ডায়নামিক সিস্টেম চালানো হচ্ছে। আসল Android ভার্সন ব্যবহার করার জন্য রিস্টার্ট করুন।"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"বাতিল করুন"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"বাতিল করুন"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"রিস্টার্ট করুন"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"রিস্টার্ট করুন"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ডায়নামিক সিস্টেম বাতিল করা হয়েছে"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ডায়নামিক সিস্টেম রিস্টার্ট বা লোড করা যাচ্ছে না"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-bs/strings.xml b/packages/DynamicSystemInstallationService/res/values-bs/strings.xml new file mode 100644 index 000000000000..84ba540bb822 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-bs/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Unesite lozinku i nastavite na dinamična ažuriranja sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamični sistem je spreman. Da ga počnete koristiti, ponovo pokrenite uređaj."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instaliranje je u toku"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Instaliranje nije uspjelo"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Potvrda slike sistema nije uspjela. Prekini instalaciju."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Dinamični sistem je sada aktivan. Ponovo pokrenite da koristite originalnu verziju Androida."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Otkaži"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Odbaci"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Ponovo pokreni"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Ponovo pokreni"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je odbačen"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nije moguće ponovo pokrenuti ili učitati dinamični sistem"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ca/strings.xml b/packages/DynamicSystemInstallationService/res/values-ca/strings.xml new file mode 100644 index 000000000000..787e4960513b --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ca/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Introdueix la contrasenya i continua cap a Actualització dinàmica del sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"El sistema dinàmic ja està a punt. Per començar a utilitzar-lo, reinicia el teu dispositiu."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instal·lació en curs"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Ha fallat la instal·lació"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"No s\'ha pogut validar la imatge. Anul·la la instal·lació."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"S\'està executant un sistema dinàmic. Reinicia per utilitzar la versió original d\'Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancel·la"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Descarta"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reinicia"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reinicia"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"S\'ha descartat el sistema dinàmic"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"No es pot reiniciar ni carregar el sistema dinàmic"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-cs/strings.xml b/packages/DynamicSystemInstallationService/res/values-cs/strings.xml new file mode 100644 index 000000000000..3dfb23f7d2ff --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-cs/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Zadejte heslo a pokračujte k dynamickým aktualizacím systému"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamický systém je připraven. Chcete-li ho začít používat, restartujte zařízení."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Probíhá instalace"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Instalace se nezdařila"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Obraz se nepodařilo ověřit. Zrušte instalaci."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Je spuštěn dynamický systém. Chcete-li použít původní verzi systému Android, restartujte zařízení."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Zrušit"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Zahodit"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restartovat"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartovat"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Zahodit dynamický systém"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dynamický systém nelze znovu spustit nebo načíst"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-da/strings.xml b/packages/DynamicSystemInstallationService/res/values-da/strings.xml new file mode 100644 index 000000000000..20005e739205 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-da/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Angiv din adgangskode, og fortsæt til Dynamiske systemopdateringer"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Det dynamiske system er klar. Hvis du vil begynde at bruge det, skal du genstarte din enhed."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation i gang"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installationen mislykkedes"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Billedet kunne ikke valideres. Afbryd installationen."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Der køres i øjeblikket et dynamisk system. Genstart for at bruge den oprindelige Android-version."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Annuller"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Afbryd"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Genstart"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Genstart"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Det dynamiske system blev slettet"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Det dynamiske system kan ikke genstartes eller indlæses"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-de/strings.xml b/packages/DynamicSystemInstallationService/res/values-de/strings.xml new file mode 100644 index 000000000000..3f000eaea251 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-de/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Gib dein Passwort ein und fahre mit Dynamic System Updates fort"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Das dynamische System kann verwendet werden. Starte dazu dein Gerät neu."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation läuft"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Fehler bei der Installation"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Fehler bei der Imagevalidierung. Die Installation wird abgebrochen."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Momentan wird ein dynamisches System ausgeführt. Durch einen Neustart kannst du zur ursprünglichen Android-Version zurückkehren."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Abbrechen"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Verwerfen"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Neu starten"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Neu starten"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamisches System verworfen"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Neustart und Laden des dynamischen Systems nicht möglich"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-el/strings.xml b/packages/DynamicSystemInstallationService/res/values-el/strings.xml new file mode 100644 index 000000000000..4d830dde12e5 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-el/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Πληκτρολογήστε τον κωδικό σας και συνεχίστε στις Δυναμικές ενημερώσεις συστήματος."</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Οι δυναμικές συστήματος είναι έτοιμες. Για να ξεκινήσετε να τις χρησιμοποιείτε, επανεκκινήστε τη συσκευή σας."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Εγκατάσταση σε εξέλιξη"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Η εγκατάσταση απέτυχε."</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Η επαλήθευση εικόνας απέτυχε. Ακύρωση εγκατάστασης."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Αυτήν τη στιγμή εκτελούνται δυναμικές συστήματος. Επανεκκινήστε για να χρησιμοποιήσετε την αρχική έκδοση Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Ακύρωση"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Απόρριψη"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Επανεκκίνηση"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Επανεκκίνηση"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Οι δυναμικές συστήματος απορρίφθηκαν."</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Δεν είναι δυνατή η επανεκκίνηση ή η φόρτωση δυναμικών συστήματος"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml new file mode 100644 index 000000000000..d72863128257 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Please enter your password and continue to Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic system is ready. To start using it, restart your device."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation in progress"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installation failed"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Image validation failed. Abort installation."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Currently running a dynamic system. Restart to use the original Android version."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancel"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Discard"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restart"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml new file mode 100644 index 000000000000..d72863128257 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Please enter your password and continue to Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic system is ready. To start using it, restart your device."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation in progress"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installation failed"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Image validation failed. Abort installation."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Currently running a dynamic system. Restart to use the original Android version."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancel"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Discard"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restart"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml new file mode 100644 index 000000000000..d72863128257 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Please enter your password and continue to Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic system is ready. To start using it, restart your device."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation in progress"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installation failed"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Image validation failed. Abort installation."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Currently running a dynamic system. Restart to use the original Android version."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancel"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Discard"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restart"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml new file mode 100644 index 000000000000..d72863128257 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Please enter your password and continue to Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic system is ready. To start using it, restart your device."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation in progress"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installation failed"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Image validation failed. Abort installation."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Currently running a dynamic system. Restart to use the original Android version."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancel"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Discard"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restart"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-en-rXC/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rXC/strings.xml new file mode 100644 index 000000000000..6ac376322ceb --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-en-rXC/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Please enter your password and continue to Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic system is ready. To start using it, restart your device."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Install in progress"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Install failed"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Image validation failed. Abort installation."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Currently running a dynamic system. Restart to use the original Android version."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancel"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Discard"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restart"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml b/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml new file mode 100644 index 000000000000..9ec819656495 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Ingresa la contraseña y continúa en Actualizaciones dinámicas del sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"El sistema dinámico está listo. Para comenzar a usarlo, reinicia el dispositivo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalación en curso"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Error de instalación"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Se produjo un error con la validación de la imagen. Anula la instalación."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Se está ejecutando el sistema dinámico. Reinicia para usar la versión original de Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancelar"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Descartar"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reiniciar"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Se descartó el sistema dinámico"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"No se puede reiniciar o cargar el sistema dinámico"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-es/strings.xml b/packages/DynamicSystemInstallationService/res/values-es/strings.xml new file mode 100644 index 000000000000..cd9db07168a2 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-es/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Introduce la contraseña y entra en Actualización Dinámica del Sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"El sistema dinámico está listo. Para comenzar a usarlo, reinicia el dispositivo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalación en curso"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"No se ha podido instalar"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"No se ha podido validar la imagen. Anula la instalación."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Se está ejecutando el sistema dinámico. Reinícialo para usar la versión original de Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancelar"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Descartar"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reiniciar"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Se ha descartado el sistema dinámico"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"No se ha podido reiniciar o cargar el sistema dinámico"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-et/strings.xml b/packages/DynamicSystemInstallationService/res/values-et/strings.xml new file mode 100644 index 000000000000..64968b60ac6f --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-et/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Sisestage oma parool ja minge edasi rakendusse Dünaamiline süsteemivärskendus"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dünaamiline süsteem on valmis. Selle kasutamise alustamiseks taaskäivitage seade."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installimine on pooleli"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installimine ebaõnnestus"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Kujutise kinnitamine ebaõnnestus. Katkestage installimine."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Praegu kasutatakse dünaamilist süsteemi. Algse Androidi versiooni kasutamiseks taaskäivitage."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Tühista"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Loobu"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Taaskäivita"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Taaskäivita"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dünaamilisest süsteemist loobuti"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dünaamilist süsteemi ei saa taaskäivitada ega laadida"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-eu/strings.xml b/packages/DynamicSystemInstallationService/res/values-eu/strings.xml new file mode 100644 index 000000000000..7c4a67d4e6c2 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-eu/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Idatzi pasahitza eta joan Sistemaren eguneratze dinamikoa eginbidera"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Prest dago sistema dinamikoa. Erabiltzen hasteko, berrabiarazi gailua."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalatzen"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Ezin izan da instalatu"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Ezin izan da balidatu irudia. Utzi bertan behera instalazioa."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Sistema dinamiko bat abian da. Berrabiarazi Android-en jatorrizko bertsioa erabiltzeko."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Utzi"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Baztertu"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Berrabiarazi"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Berrabiarazi"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Baztertu da sistema dinamikoa"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Ezin da berrabiarazi edo kargatu sistema dinamikoa"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-fa/strings.xml b/packages/DynamicSystemInstallationService/res/values-fa/strings.xml new file mode 100644 index 000000000000..7533e71cb26c --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-fa/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"لطفاً گذرواژه را وارد کنید و «بهروزرسانیهای سیستم پویا» را ادامه دهید"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"سیستم پویا آماده است. برای استفاده از آن، دستگاه را بازراهاندازی کنید."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"درحال نصب"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"نصب نشد"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"راستیآزمایی تصویر انجام نشد. نصب را لغو کنید."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"درحالحاضر سیستم پویا اجرا میشود. برای استفاده از نسخه اصلی Android، بازراهاندازی کنید."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"لغو کردن"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"صرفنظر کردن"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"بازراهاندازی"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"بازراهاندازی"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"از سیستم پویا صرفنظر شد"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"نمیتوان سیستم پویا را بازراهاندازی یا بار کرد"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-fi/strings.xml b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml new file mode 100644 index 000000000000..948c3336cea8 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Lisää salasanasi ja jatka dynaamisiin järjestelmäpäivityksiin"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynaaminen järjestelmä on valmis. Aloita sen käyttö käynnistämällä laite uudelleen."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Asennus käynnissä"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Asennus epäonnistui"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Kuvavahvistus epäonnistui. Keskeytä asennus."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Käyttää tällä hetkellä dynaamista järjestelmää. Käynnistä uudelleen käyttääksesi alkuperäistä Android-versiota."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Peruuta"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Hylkää"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Käynn. uudelleen"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Käynn. uudelleen"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynaaminen järjestelmä hylätty"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dynaamista järjestelmää ei voi käynnistää uudelleen tai ladata"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml b/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000000..6e2f235bcb76 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Veuillez entrer votre mot de passe et continuer vers les mises à jour système dynamiques"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Le système dynamique est prêt. Pour commencer à l\'utiliser, redémarrez votre appareil."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation en cours…"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Échec de l\'installation"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Impossible de valider l\'image. Annulation de l\'installation."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Un système dynamique est en cours d\'exécution. Pour utiliser la version originale d\'Android, redémarrez l\'appareil."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Annuler"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Annuler"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Redémarrer"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Redémarrer"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Système dynamique supprimé"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Impossible de redémarrer ou de charger le système dynamique"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-fr/strings.xml b/packages/DynamicSystemInstallationService/res/values-fr/strings.xml new file mode 100644 index 000000000000..67f799731c6d --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-fr/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Veuillez saisir votre mot de passe pour accéder aux Mises à jour système dynamiques"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Le système dynamique est prêt. Pour commencer à l\'utiliser, redémarrez votre appareil."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation…"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Échec de l\'installation"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Échec de la validation de l\'image. Annulez l\'installation."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Un système dynamique est en cours d\'exécution. Redémarrez pour utiliser la version Android d\'origine."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Annuler"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Supprimer"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Redémarrer"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Redémarrer"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Système dynamique supprimé"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Impossible de redémarrer ou de charger le système dynamique"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-gl/strings.xml b/packages/DynamicSystemInstallationService/res/values-gl/strings.xml new file mode 100644 index 000000000000..8ea6d1c6c3b6 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-gl/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Pon o teu contrasinal e vai a Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"O sistema dinámico está listo. Para utilizalo, reinicia o dispositivo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalación en curso"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Produciuse un erro durante a instalación"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Produciuse un erro ao validar a imaxe. Aborta a instalación."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Estase executando un sistema dinámico. Reinicia o dispositivo para utilizar a versión de Android orixinal."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancelar"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Descartar"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reiniciar"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Descartouse o sistema dinámico"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Non se puido reiniciar nin cargar o sistema dinámico"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-gu/strings.xml b/packages/DynamicSystemInstallationService/res/values-gu/strings.xml new file mode 100644 index 000000000000..aec18049fdb0 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-gu/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"કૃપા કરીને તમારો પાસવર્ડ દાખલ કરો અને ડાઇનૅમિક સિસ્ટમ અપડેટ પર ચાલુ રાખો"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ડાઇનૅમિક સિસ્ટમ તૈયાર છે. તેનો ઉપયોગ કરવા માટે, તમારા ડિવાઇસને ફરી શરૂ કરો."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ઇન્સ્ટૉલ થઈ રહ્યું છે"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ઇન્સ્ટૉલ કરવામાં નિષ્ફળ રહ્યાં"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"છબીની ચકાસણી નિષ્ફળ રહી. ઇન્સ્ટૉલેશન રદ કરો."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"હાલમાં ડાઇનૅમિક સિસ્ટમ ચાલી રહી છે. ઑરિજિનલ Android વર્ઝનનો ઉપયોગ કરવા માટે ફરી શરૂ કરો."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"રદ કરો"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"કાઢી નાખો"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ફરી શરૂ કરો"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ફરી શરૂ કરો"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ડાઇનૅમિક સિસ્ટમ કાઢી નાખવામાં આવી"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ડાઇનૅમિક સિસ્ટમને ફરી શરૂ અથવા લોડ કરી શકાતી નથી"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-hi/strings.xml b/packages/DynamicSystemInstallationService/res/values-hi/strings.xml new file mode 100644 index 000000000000..efedbe8e7ee6 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-hi/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"डाइनैमिक सिस्टम अपडेट की सुविधा जारी रखने के लिए कृपया अपना पासवर्ड डालें"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"डाइनैमिक सिस्टम तैयार है. इसका इस्तेमाल करने के लिए, अपना डिवाइस रीस्टार्ट करें."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"इंस्टॉल हो रहा है"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"इंस्टॉल नहीं हो सका"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"इमेज की पुष्टि नहीं हो सकी. इंस्टॉल करने की प्रक्रिया रद्द करें."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"फ़िलहाल, हम एक डाइनैमिक सिस्टम चला रहे हैं. Android का मूल वर्शन इस्तेमाल करने के लिए रीस्टार्ट करें."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"रद्द करें"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"खारिज करें"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"रीस्टार्ट करें"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"रीस्टार्ट करें"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"डाइनैमिक सिस्टम खारिज किया गया"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"डाइनैमिक सिस्टम रीस्टार्ट या लोड नहीं हो सका"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-hr/strings.xml b/packages/DynamicSystemInstallationService/res/values-hr/strings.xml new file mode 100644 index 000000000000..50ceaa16f764 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-hr/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Unesite zaporku i nastavite do dinamičnih ažuriranja sustava"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamični sustav je spreman. Da biste ga počeli upotrebljavati, ponovno pokrenite svoj uređaj."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalacija u tijeku"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Instaliranje nije uspjelo"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Provjera slike nije uspjela. Prekini instalaciju."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Trenutačno je pokrenut dinamični sustav. Ponovno pokrenite kako biste upotrebljavali izvornu verziju Androida."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Otkaži"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Odbaci"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Pokreni"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Pokreni"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Odbačeni dinamični sustav"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nije moguće ponovno pokretanje ili učitavanje dinamičnog sustava"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-hu/strings.xml b/packages/DynamicSystemInstallationService/res/values-hu/strings.xml new file mode 100644 index 000000000000..94afa3b927b3 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-hu/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Adja meg jelszavát, hogy használhassa a Dinamikus rendszerfrissítések funkciót"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"A dinamikus rendszer készen áll. A használatához indítsa újra az eszközt."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Telepítés…"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Sikertelen telepítés"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"A kép ellenőrzése nem sikerült. A telepítés megszakad."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Jelenleg dinamikus rendszert futtat. Az eredeti Android-verzió használatához indítsa újra az eszközt."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Mégse"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Elvetés"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Újraindítás"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Újraindítás"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Elvetett dinamikus rendszer"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nem lehet újraindítani vagy betölteni a dinamikus rendszert"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-hy/strings.xml b/packages/DynamicSystemInstallationService/res/values-hy/strings.xml new file mode 100644 index 000000000000..b0cd740d3e8d --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-hy/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Մուտքագրեք ձեր գաղտնաբառը և անցեք համակարգի դինամիկ թարմացումների էջ"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Դինամիկ համակարգը պատրաստ է։ Այն օգտագործելու համար վերագործարկեք ձեր սարքը։"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Տեղադրում"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Չհաջողվեց տեղադրել"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Չհաջողվեց հաստատել պատկերը։ Չեղարկել տեղադրումը։"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Աշխատեցվում է դինամիկ համակարգը։ Վերագործարկեք՝ Android-ի նախկին տարբերակին անցնելու համար։"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Չեղարկել"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Հրաժարվել"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"վերականգնել"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Վերագործարկել"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Դինամիկ համակարգի գործարկումը չեղարկվեց"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Չհաջողվեց վերագործարկել կամ բեռնել դինամիկ համակարգը"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-in/strings.xml b/packages/DynamicSystemInstallationService/res/values-in/strings.xml new file mode 100644 index 000000000000..44b4aeec8b78 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-in/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Masukkan sandi Anda dan lanjutkan ke Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic System sudah siap. Mulai ulang perangkat untuk mulai menggunakannya."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Sedang diinstal"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Penginstalan gagal"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Validasi image gagal. Batalkan penginstalan."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Saat ini sedang menjalankan Dynamic System. Mulai ulang untuk menggunakan Android versi asli."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Batal"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Hapus"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Mulai ulang"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Mulai ulang"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamic System dihapus"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Tidak dapat memulai ulang atau memuat Dynamic System"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-is/strings.xml b/packages/DynamicSystemInstallationService/res/values-is/strings.xml new file mode 100644 index 000000000000..048d1bca5518 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-is/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Sláðu inn aðgangsorð og haltu áfram í „Breytilegar kerfisuppfærslur“"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Breytilegt kerfi er tilbúið. Endurræstu tækið til að byrja að nota það."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Uppsetning stendur yfir"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Uppsetning mistókst"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Ekki tókst að staðfesta mynd. Hættu við uppsetninguna."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Tækið keyrir á breytilegu kerfi. Endurræstu til að nota upprunalega Android útgáfu."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Hætta við"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Fleygja"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Endurræsa"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Endurræsa"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Breytilegu kerfi fleygt"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Ekki tókst að endurræsa eða hlaða breytilegu kerfi"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-it/strings.xml b/packages/DynamicSystemInstallationService/res/values-it/strings.xml new file mode 100644 index 000000000000..f70b38178021 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-it/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Inserisci la password e continua su Aggiornamenti di sistema dinamici"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Sistema dinamico pronto. Per iniziare a usarlo, riavvia il dispositivo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installazione in corso"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installazione non riuscita"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Impossibile convalidare l\'immagine. Interrompi l\'installazione."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Sistema dinamico in uso. Riavvia per usare la versione di Android originale."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Annulla"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Annulla"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Riavvia"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Riavvia"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinamico annullato"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Impossibile riavviare o caricare il sistema dinamico"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-iw/strings.xml b/packages/DynamicSystemInstallationService/res/values-iw/strings.xml new file mode 100644 index 000000000000..aff7c824ba1d --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-iw/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"יש להזין את הסיסמה ולהמשיך אל עדכוני המערכת הדינמיים"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"המערכת הדינמית מוכנה. כדי להתחיל להשתמש בה, יש להפעיל מחדש את המכשיר."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ההתקנה מתבצעת"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ההתקנה נכשלה"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"אימות התמונה נכשל. יש לבטל את ההתקנה."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"בשלב זה פועלת מערכת דינמית. כדי להשתמש בגרסת Android המקורית, יש לבצע הפעלה מחדש."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ביטול"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"סגירה"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"הפעלה מחדש"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"הפעלה מחדש"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"המערכת הדינמית נסגרה"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"לא ניתן להפעיל מחדש או לטעון את המערכת הדינמית"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ja/strings.xml b/packages/DynamicSystemInstallationService/res/values-ja/strings.xml new file mode 100644 index 000000000000..46c093057a49 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ja/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"パスワードを入力し、Dynamic System Updates に移動してください"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"動的システムの準備ができました。使い始めるには、デバイスを再起動してください。"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"インストールしています"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"インストールに失敗しました"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"イメージの検証に失敗しました。インストールを中止してください。"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"現在、動的システムを実行しています。元の Android バージョンを使用するには再起動してください。"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"キャンセル"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"破棄"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"再起動"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"再起動"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"動的システムを破棄しました"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"動的システムの再起動や読み込みを行えません"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ka/strings.xml b/packages/DynamicSystemInstallationService/res/values-ka/strings.xml new file mode 100644 index 000000000000..f841a59801e4 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ka/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"გთხოვთ, შეიყვანოთ პაროლი სისტემის დინამიურ განახლებებზე გადასასვლელად"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"დინამიური სისტემა მზადაა. გადატვირთეთ მოწყობილობა მის გამოსაყენებლად."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ინსტალირდება"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ინსტალაცია ვერ მოხერხდა"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"სურათის ვალიდაცია ვერ მოხერხდა. ინსტალაციის შეწყვეტა."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ამჟამად გამოიყენება დინამიური სისტემა. გადატვირთეთ Android-ის ორიგინალი ვერსიის გამოსაყენებლად."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"გაუქმება"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"გაუქმება"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"გადატვირთვა"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"გადატვირთვა"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"გაუქმებული დინამიური სისტემა"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"დინამიური სისტემის გადატვირთვა ან ჩატვირთვა ვერ ხერხდება"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-kk/strings.xml b/packages/DynamicSystemInstallationService/res/values-kk/strings.xml new file mode 100644 index 000000000000..d367b614e528 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-kk/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Құпия сөзіңізді енгізіңіз және Dynamic System Updates функциясына өтіңіз."</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамикалық жүйе дайын. Оны пайдалану үшін құрылғыңызды қайта қосыңыз."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Орнатылып жатыр."</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Орнатылмады."</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Кескін тексерілмеді. Орнатуды доғарыңыз."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Әзірге динамикалық жүйе пайдаланылуда. Бастапқы Android нұсқасын пайдалану үшін қайта қосыңыз."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Бас тарту"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Жабу"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Қайта қосу"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Қайта қосу"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамикалық жүйе өшірілді."</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамикалық жүйені қайта қосу не жүктеу мүмкін емес."</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-km/strings.xml b/packages/DynamicSystemInstallationService/res/values-km/strings.xml new file mode 100644 index 000000000000..56a37164fa6e --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-km/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"សូមបញ្ចូលពាក្យសម្ងាត់របស់អ្នក រួចបន្តទៅការដំឡើងកំណែប្រព័ន្ធឌីណាមិច"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ប្រព័ន្ធឌីណាមិចអាចប្រើបានហើយ។ ដើម្បីចាប់ផ្ដើមប្រើប្រព័ន្ធឌីណាមិច សូមចាប់ផ្ដើមឧបករណ៍របស់អ្នកឡើងវិញ។"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ការដំឡើងកំពុងដំណើរការ"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ការដំឡើងមិនបានសម្រេច"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"បញ្ជាក់ភាពត្រឹមត្រូវនៃរូបភាពមិនបានសម្រេច។ បោះបង់ការដំឡើង។"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"បច្ចុប្បន្នកំពុងដំណើរការប្រព័ន្ធឌីណាមិច។ ចាប់ផ្ដើមឡើងវិញ ដើម្បីប្រើកំណែ Android ដើម។"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"បោះបង់"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"លុបចោល"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ចាប់ផ្ដើមឡើងវិញ"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ចាប់ផ្ដើមឡើងវិញ"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"បានលុបចោលប្រព័ន្ធឌីណាមិច"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"មិនអាចចាប់ផ្ដើមឡើងវិញ ឬផ្ទុកប្រព័ន្ធឌីណាមិចបានទេ"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-kn/strings.xml b/packages/DynamicSystemInstallationService/res/values-kn/strings.xml new file mode 100644 index 000000000000..b4063df9c10d --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-kn/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ ನಂತರ ಡೈನಾಮಿಕ್ ಸಿಸ್ಟಂ ಅಪ್ಡೇಟ್ಗಳಿಗೆ ಮುಂದುವರಿಯಿರಿ"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ಡೈನಾಮಿಕ್ ಸಿಸ್ಟಂ ಸಿದ್ದವಾಗಿದೆ. ಇದನ್ನು ಬಳಸಲು, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿ."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ಇನ್ಸ್ಟಾಲ್ ಆಗುತ್ತಿದೆ"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ಚಿತ್ರದ ಮೌಲ್ಯೀಕರಣ ವಿಫಲವಾಗಿದೆ. ಇನ್ಸ್ಟಾಲ್ ಮಾಡುವಿಕೆಯನ್ನು ರದ್ದುಗೊಳಿಸಿ."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ಪ್ರಸ್ತುತವಾಗಿ ಡೈನಾಮಿಕ್ ಸಿಸ್ಟಂ ರನ್ ಆಗುತ್ತಿದೆ ಮೂಲ Android ಆವೃತ್ತಿ ಬಳಸಲು, ಮರುಪ್ರಾರಂಭಿಸಿ."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ರದ್ದುಗೊಳಿಸಿ"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"ತ್ಯಜಿಸಿ"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ಮರುಪ್ರಾರಂಭಿಸಿ"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ಮರುಪ್ರಾರಂಭಿಸಿ"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ಡೈನಮಿಕ್ ಸಿಸ್ಟಂ ಅನ್ನು ತ್ಯಜಿಸಲಾಗಿದೆ"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ಡೈನಾಮಿಕ್ ಸಿಸ್ಟಂ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಅಥವಾ ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ko/strings.xml b/packages/DynamicSystemInstallationService/res/values-ko/strings.xml new file mode 100644 index 000000000000..24ac9245e22c --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ko/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"비밀번호를 입력하고 동적 시스템 업데이트를 계속 진행하세요."</string> + <string name="notification_install_completed" msgid="6252047868415172643">"동적 시스템이 준비되었습니다. 사용을 시작하려면 기기를 다시 시작하세요."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"설치 진행 중"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"설치할 수 없음"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"이미지를 확인할 수 없습니다. 설치를 취소합니다."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"현재 동적 시스템을 실행 중입니다. 기존의 Android 버전을 사용하려면 다시 시작하세요."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"취소"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"삭제"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"다시 시작"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"다시 시작"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"동적 시스템 삭제됨"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"동적 시스템을 다시 시작하거나 로드할 수 없음"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ky/strings.xml b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml new file mode 100644 index 000000000000..a4387e7bf4a1 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Сырсөзүңүздү киргизип, системаны динамикалык жаңыртууга өтүңүз"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамикалык система даяр. Аны колдонуу үчүн, түзмөктү өчүрүп күйгүзүңүз."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Орнотулууда"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Орнотулбай койду"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Сүрөт текшерилбей калды. Орнотууну токтотуңуз."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Учурда динамикалык система колдонулууда. Android\'дин түпнуска версиясын колдонуу үчүн, өчүрүп күйгүзүңүз."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Жок"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Жоюу"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Өчүрүп күйгүзүү"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Өчүрүп күйгүзүү"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамикалык система жоюлду"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамикалык система өчүрүлүп күйгүзүлбөй же жүктөлбөй жатат"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-lo/strings.xml b/packages/DynamicSystemInstallationService/res/values-lo/strings.xml new file mode 100644 index 000000000000..f17ca16bf777 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-lo/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"ກະລຸນາໃສ່ລະຫັດຜ່ານຂອງທ່ານ ແລະ ດຳເນີນການຕໍ່ຫາອັບເດດລະບົບແບບໄດນາມິກ"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ລະບົບໄດນາມິກພ້ອມແລ້ວ. ກະລຸນາຣີສະຕາດອຸປະກອນຂອງທ່ານເພື່ອເລີ່ມນຳໃຊ້ມັນ."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ກຳລັງຕິດຕັ້ງຢູ່"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ຕິດຕັ້ງບໍ່ສຳເລັດ"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ການກວດສອບໄຟລ໌ຮູບບໍ່ສຳເລັດ. ຍົກເລີກການຕິດຕັ້ງ."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ຕອນນີ້ກຳລັງໃຊ້ລະບົບໄດນາມິກ. ກະລຸນາຣີສະຕາດເພື່ອໃຊ້ເວີຊັນ Android ຕົ້ນສະບັບ."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ຍົກເລີກ"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"ປິດໄວ້"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ຣີສະຕາດ"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ຣີສະຕາດ"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ລະບົບໄດນາມິກທີ່ຍົກເລີກແລ້ວ"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ບໍ່ສາມາດຣີສະຕາດ ຫຼື ໂຫຼດລະບົບໄດນາມິກໄດ້"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-lt/strings.xml b/packages/DynamicSystemInstallationService/res/values-lt/strings.xml new file mode 100644 index 000000000000..8128eb7b0a72 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-lt/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Įveskite slaptažodį ir eikite į Dinaminių sistemos atnaujinimų funkciją"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinaminė sistema paruošta. Jei norite pradėti ją naudoti, paleiskite įrenginį iš naujo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Diegiama"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Įdiegti nepavyko"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Nepavyko patvirtinti vaizdo. Nutraukti diegimą."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Šiuo metu paleista dinaminė sistema. Paleiskite iš naujo, jei norite naudoti pradinę „Android“ versiją."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Atšaukti"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Atmesti"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Pal. iš naujo"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Pal. iš naujo"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinaminė sistema atmesta"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nepavyko paleisti iš naujo ar įkelti dinaminės sistemos"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-lv/strings.xml b/packages/DynamicSystemInstallationService/res/values-lv/strings.xml new file mode 100644 index 000000000000..cfe7a087e148 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-lv/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Ievadiet paroli un pārejiet uz funkciju Dinamiskie sistēmas atjauninājumi"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamiskā sistēma ir gatava. Lai sāktu to izmantot, restartējiet ierīci."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Notiek instalēšana"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Instalēšana neizdevās"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Attēla validācija neizdevās. Instalācija tiek priekšlaikus pārtraukta."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Pašlaik darbojas dinamiska sistēma. Lai izmantotu sākotnējo Android versiju, restartējiet ierīci."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Atcelt"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Atmest"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restartēt"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartēt"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamiskā sistēma tika atmesta"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nevar restartēt vai ielādēt dinamisko sistēmu"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-mk/strings.xml b/packages/DynamicSystemInstallationService/res/values-mk/strings.xml new file mode 100644 index 000000000000..21215aa77631 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-mk/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Внесете ја вашата лозинка и продолжете на „Динамични системски ажурирања“"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамичниот систем е подготвен. За да започнете со користење, рестартирајте го уредот."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Инсталирањето е во тек"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Неуспешно инсталирање"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Проверката на сликата не успеа. Прекини ја инсталацијата."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Во моментов се извршува динамичен систем. Рестартирајте за да ја користите оригиналната верзија на Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Откажи"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Отфрли"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Рестартирај"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартирај"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Отфрлен динамичен систем"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не може да го рестартира или вчита динамичниот систем"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ml/strings.xml b/packages/DynamicSystemInstallationService/res/values-ml/strings.xml new file mode 100644 index 000000000000..951a0b95f7e4 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ml/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"നിങ്ങളുടെ പാസ്വേഡ് നൽകി ഡൈനാമിക് സിസ്റ്റം അപ്ഡേറ്റുകളിലേക്ക് പോകുക"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ഡെെനാമിക് സിസ്റ്റം തയ്യാറാണ്. അത് ഉപയോഗിച്ച് തുടങ്ങാൻ നിങ്ങളുടെ ഉപകരണം റീസ്റ്റാർട്ട് ചെയ്യുക."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ഇൻസ്റ്റാൾ ചെയ്യൽ പുരോഗതിയിലാണ്"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ഇൻസ്റ്റാൾ ചെയ്യാനായില്ല"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ചിത്രത്തിന്റെ മൂല്യനിർണ്ണയം നടത്താനായില്ല. ഇൻസ്റ്റലേഷൻ റദ്ദാക്കുക."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"നിലവിൽ ഒരു ഡെെനാമിക് സിസ്റ്റം റൺ ചെയ്യുന്നുണ്ട്. ഒറിജിനൽ Android പതിപ്പ് ഉപയോഗിക്കാൻ റീസ്റ്റാർട്ട് ചെയ്യുക."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"റദ്ദാക്കുക"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"നിരസിക്കുക"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"റീസ്റ്റാർട്ട് ചെയ്യൂ"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"റീസ്റ്റാർട്ട് ചെയ്യൂ"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ഡെെനാമിക് സിസ്റ്റം നിരസിച്ചു"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"റീസ്റ്റാർട്ട് ചെയ്യാനോ ഡെെനാമിക് സിസ്റ്റം ലോഡ് ചെയ്യാനോ ആവില്ല"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-mn/strings.xml b/packages/DynamicSystemInstallationService/res/values-mn/strings.xml new file mode 100644 index 000000000000..d0965d021c65 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-mn/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Нууц үгээ оруулаад Динамик системийн шинэчлэлтийг үргэлжлүүлнэ үү"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамик систем бэлэн боллоо. Түүнийг ашиглаж эхлэхийн тулд төхөөрөмжөө дахин эхлүүлнэ үү."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Суулгаж байна"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Суулгаж чадсангүй"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Системийн хуулбарын баталгаажуулалт амжилтгүй боллоо. Суулгах үйлдлийг зогсооно уу."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Одоогоор динамик системийг ажиллуулж байна. Android-н эх хувилбарыг ашиглахын тулд дахин эхлүүлнэ үү."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Болих"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Болих"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Дахин эхлүүлэх"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Дахин эхлүүлэх"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамик системийг устгасан"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамик системийг дахин эхлүүлэх эсвэл ачаалах боломжгүй байна"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-mr/strings.xml b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml new file mode 100644 index 000000000000..268e1d344620 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"कृपया तुमचा पासवर्ड एंटर करा आणि डायनॅमिक सिस्टम अपडेट वर जा"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"डायनॅमिक सिस्टम तयार आहे. ती वापरणे सुरू करण्यासाठी, तुमचे डिव्हाइस रीस्टार्ट करा."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"इंस्टॉल प्रगतीपथावर आहे"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"इंस्टॉल करता आली नाही"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"इमेज प्रमाणीकरण करता आले नाही. इंस्टॉलेशन रद्द करा."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"सध्या डायनॅमिक सिस्टम रन करत आहे. मूळ Android आवृत्ती वापरण्यासाठी रीस्टार्ट करा."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"रद्द करा"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"काढून टाका"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"रीस्टार्ट करा"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"रीस्टार्ट करा"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"डायनॅमिक सिस्टम काढून टाकली"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"डायनॅमिक सिस्टम रीस्टार्ट किंवा लोड करू शकत नाही"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ms/strings.xml b/packages/DynamicSystemInstallationService/res/values-ms/strings.xml new file mode 100644 index 000000000000..bba8b9724f0d --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ms/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Sila masukkan kata laluan dan teruskan ke Kemas Kini Sistem Dinamik"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Sistem dinamik sudah sedia. Untuk mula menggunakan sistem ini, mulakan semula peranti anda"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Pemasangan sedang dijalankan"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Pemasangan gagal"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Gagal mengesahkan imej. Henti paksa pemasangan."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Sedang menjalankan sistem dinamik. Mulakan semula peranti untuk menggunakan versi asal Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Batal"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Buang"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Mulakan semula"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Mulakan semula"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistem dinamik dibuang"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Tidak dapat memulakan semula atau memuatkan sistem dinamik"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-my/strings.xml b/packages/DynamicSystemInstallationService/res/values-my/strings.xml new file mode 100644 index 000000000000..b2488ece9ce3 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-my/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"သင့်စကားဝှက်ထည့်ပြီး ပြောင်းလဲနိုင်သော စနစ်အပ်ဒိတ်များသို့ ရှေ့ဆက်ပါ"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ပြောင်းလဲနိုင်သောစနစ် အသင့်ဖြစ်ပါပြီ။ ၎င်းကို စတင်အသုံးပြုရန် သင့်စက်ကို ပြန်စပါ။"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ထည့်သွင်းနေဆဲဖြစ်သည်"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ထည့်သွင်း၍မရပါ"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ပုံအတည်ပြု၍ မရပါ။ ထည့်သွင်းမှုကို ရပ်ပါ။"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"လက်ရှိတွင် ပြောင်းလဲနိုင်သောစနစ်ကို အသုံးပြုနေသည်။ မူလ Android ဗားရှင်း အသုံးပြုရန် ပြန်စတင်ပါ။"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"မလုပ်တော့"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"ဖယ်ပစ်ရန်"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ပြန်စရန်"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ပြန်စရန်"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ပြောင်းလဲနိုင်သောစနစ်ကို ဖယ်လိုက်သည်"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ပြန်စ၍ မရပါ (သို့) ပြောင်းလဲနိုင်သောစနစ် ဖွင့်၍မရပါ"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-nb/strings.xml b/packages/DynamicSystemInstallationService/res/values-nb/strings.xml new file mode 100644 index 000000000000..36e3d6912e23 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-nb/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Skriv inn passordet ditt, og fortsett til dynamiske systemoppdateringer"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Det dynamiske systemet er klart. Start enheten din på nytt for å begynne å bruke det."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installeringen pågår"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installeringen mislyktes"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Bildebekreftelsen mislyktes. Avbryt installeringen."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Kjører et dynamisk system nå. Start på nytt for å bruke den opprinnelige Android-versjonen."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Avbryt"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Forkast"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Start på nytt"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Start på nytt"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Det dynamiske systemet er forkastet"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Det dynamiske systemet kan ikke startes på nytt eller lastes inn"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ne/strings.xml b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml new file mode 100644 index 000000000000..ee9267852250 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"कृपया आफ्नो पासवर्ड प्रविष्टि गर्नुहोस् र Dynamic System Updates को प्रक्रियालाई निरन्तरता दिनुहोस्"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic System तयार छ। यसको प्रयोग सुरु गर्न आफ्नो यन्त्र रिस्टार्ट गर्नुहोस्।"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"इन्स्टल हुँदै छ"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"स्थापना गर्न सकिएन"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"छवि पुष्टि गर्न सकिएन। स्थापना गर्ने प्रक्रिया रद्द गर्नुहोस्।"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"हाल Dynamic System चलिरहेको छ। Android को मूल संस्करण प्रयोग गर्न यन्त्र रिस्टार्ट गर्नुहोस्।"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"रद्द गर्नुहोस्"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"खारेज गर्नुहोस्"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"रिस्टार्ट गर्नु…"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"रिस्टार्ट गर्नु…"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamic System खारेज गरियो"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"रिस्टार्ट गर्न वा Dynamic System लोड गर्न सकिएन"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml new file mode 100644 index 000000000000..47eeb839c6dc --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Geef je wachtwoord op en ga door naar \'Dynamische systeemupdates\'"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamisch systeem is gereed. Start je apparaat opnieuw op om het te gebruiken."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installatie wordt uitgevoerd"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installatie mislukt"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Valideren van afbeelding mislukt. Installatie afbreken."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Er is momenteel een dynamisch systeem actief. Start je apparaat opnieuw op om de oorspronkelijke Android-versie te gebruiken."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Annuleren"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Niet opslaan"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Herstarten"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Herstarten"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamisch systeem niet opgeslagen"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Kan dynamisch systeem niet opnieuw opstarten of laden"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-or/strings.xml b/packages/DynamicSystemInstallationService/res/values-or/strings.xml new file mode 100644 index 000000000000..e0c847094844 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-or/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"ଦୟାକରି ଆପଣଙ୍କ ପାସୱାର୍ଡ ଲେଖନ୍ତୁ ଏବଂ ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଅପଡେଟ୍ ଜାରି ରଖନ୍ତୁ"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ପ୍ରସ୍ତୁତ ଅଛି। ଏହାକୁ ବ୍ୟବହାର କରିବା ଆରମ୍ଭ କରିବାକୁ, ଆପଣଙ୍କ ଡିଭାଇସକୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ।"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ଇନଷ୍ଟଲ୍ ହେଉଛି"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ଇନଷ୍ଟଲ୍ କରିବା ବିଫଳ ହୋଇଛି"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ଛବି ବୈଧକରଣ ବିଫଳ ହୋଇଛି। ଇନଷ୍ଟଲେସନ୍ ରଦ୍ଦ କରନ୍ତୁ।"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ବର୍ତ୍ତମାନ ଏକ ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଚାଲୁଛି। ମୂଳ Android ସଂସ୍କରଣ ବ୍ୟବହାର କରିବାକୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ।"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"ଖାରଜ କରନ୍ତୁ"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଖାରଜ କରାଯାଇଛି"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ରିଷ୍ଟାର୍ଟ କିମ୍ବା ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-pa/strings.xml b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml new file mode 100644 index 000000000000..c5f7a3d38cdc --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ ਅਤੇ ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਅੱਪਡੇਟ \'ਤੇ ਜਾਰੀ ਰੱਖੋ"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਤਿਆਰ ਹੈ। ਇਸ ਦੀ ਵਰਤੋਂ ਸ਼ੁਰੂ ਕਰਨ ਲਈ, ਆਪਣਾ ਡੀਵਾਈਸ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ।"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ਸਥਾਪਨਾ ਜਾਰੀ ਹੈ"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ਚਿੱਤਰ ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ ਰਹੀ। ਸਥਾਪਨਾ ਨੂੰ ਰੱਦ ਕਰੋ।"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ਫ਼ਿਲਹਾਲ ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਚੱਲ ਰਿਹਾ ਹੈ। ਮੂਲ Android ਵਰਜਨ ਵਰਤਣ ਲਈ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ।"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ਰੱਦ ਕਰੋ"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"ਖਾਰਜ ਕਰੋ"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਰੱਦ ਕੀਤਾ ਗਿਆ"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਮੁੜ-ਸ਼ੁਰੂ ਜਾਂ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-pl/strings.xml b/packages/DynamicSystemInstallationService/res/values-pl/strings.xml new file mode 100644 index 000000000000..bc7d5fe5b222 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-pl/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Wpisz hasło i przejdź do dynamicznych aktualizacji systemu"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"System dynamiczny jest gotowy. Aby zacząć go używać, uruchom urządzenie ponownie."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instaluję"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Nie udało się zainstalować"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Nie udało się zweryfikować obrazu. Przerwij instalację."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Obecnie urządzenie korzysta z systemu dynamicznego. Aby powrócić do oryginalnej wersji Androida, uruchom urządzenie ponownie."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Anuluj"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Odrzuć"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Uruchom ponownie"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Uruchom ponownie"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Usunięto system dynamiczny"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nie można ponownie uruchomić lub wczytać systemu dynamicznego"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000000..31a9bb439235 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Digite sua senha e prossiga para Atualizações dinâmicas do sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"O sistema dinâmico está pronto. Para começar a usá-lo, reinicie o dispositivo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalação em andamento"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Falha na instalação"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Falha ao validar imagem. Cancele a instalação."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Um sistema dinâmico está sendo executado no momento. Reinicie para usar a versão original do Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancelar"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Descartar"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reiniciar"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinâmico descartado"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Não é possível reiniciar ou carregar o sistema dinâmico"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000000..d917c6afec6e --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Introduza a sua palavra-passe e continue para a Atualização Dinâmica do Sistema."</string> + <string name="notification_install_completed" msgid="6252047868415172643">"O sistema dinâmico está pronto. Para o começar a utilizar, reinicie o dispositivo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalação em curso"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Falha na instalação"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Falha ao validar a imagem. A instalação foi interrompida."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Está atualmente em execução um sistema dinâmico. Reinicie para utilizar a versão original do Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancelar"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Rejeitar"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reiniciar"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinâmico rejeitado"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Não é possível reiniciar ou carregar o sistema dinâmico."</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-pt/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt/strings.xml new file mode 100644 index 000000000000..31a9bb439235 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-pt/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Digite sua senha e prossiga para Atualizações dinâmicas do sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"O sistema dinâmico está pronto. Para começar a usá-lo, reinicie o dispositivo."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalação em andamento"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Falha na instalação"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Falha ao validar imagem. Cancele a instalação."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Um sistema dinâmico está sendo executado no momento. Reinicie para usar a versão original do Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Cancelar"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Descartar"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reiniciar"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinâmico descartado"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Não é possível reiniciar ou carregar o sistema dinâmico"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ro/strings.xml b/packages/DynamicSystemInstallationService/res/values-ro/strings.xml new file mode 100644 index 000000000000..c21131857830 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ro/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Introduceți parola și accesați Actualizările de sistem dinamice"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Sistemul dinamic este pregătit. Ca să începeți să-l folosiți, reporniți dispozitivul."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Se instalează"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Instalarea nu a reușit"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Nu s-a validat imaginea. Abandonați instalarea."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Rulăm un sistem dinamic. Reporniți pentru a folosi versiunea Android inițială."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Anulați"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Renunțați"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reporniți"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reporniți"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"S-a renunțat la sistemul dinamic"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nu se poate reporni sau încărca sistemul dinamic"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ru/strings.xml b/packages/DynamicSystemInstallationService/res/values-ru/strings.xml new file mode 100644 index 000000000000..bf94c99b8fb5 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ru/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Введите пароль и перейдите к динамическим обновлениям системы."</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамическая система готова. Чтобы использовать ее, перезапустите устройство."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Идет установка…"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Ошибка установки."</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Не удалось проверить образ. Отмените установку."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Используется динамическая система. Чтобы вернуться к исходной версии Android, перезапустите устройство."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Отмена"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Отменить"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Перезапустить"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Перезапустить"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамическая система удалена."</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не удается запустить или загрузить динамическую систему."</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-si/strings.xml b/packages/DynamicSystemInstallationService/res/values-si/strings.xml new file mode 100644 index 000000000000..e6a6ea2fe351 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-si/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"කරුණාකර ඔබගේ මුරපදය ඇතුළත් කර ගතික පද්ධති යාවත්කාලීන කිරීම් වෙත යන්න"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ගතික පද්ධතිය සූදානම්ය. එය භාවිතා කිරීම ආරම්භ කිරීමට, ඔබගේ උපාංගය නැවත ආරම්භ කරන්න."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ස්ථාපනය කෙරෙමින් පවතී"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ස්ථාපනය අසාර්ථක විය"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"රූප වලංගු කිරීම අසාර්ථක විය. ස්ථාපනය අවලංගු කරන්න"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"දැනට ගතික පද්ධතියක් ක්රියාත්මක කරයි. මුල් Android අනුවාදය භාවිතා කිරීමට නැවත ආරම්භ කරන්න."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"අවලංගු කරන්න"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"ඉවත ලන්න"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"යළි අරඹන්න"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"යළි අරඹන්න"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ගතික පද්ධතිය ඉවත දමන ලදි"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ගතික පද්ධතිය නැවත ආරම්භ කිරීමට හෝ පූරණය කිරීමට නොහැක"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-sk/strings.xml b/packages/DynamicSystemInstallationService/res/values-sk/strings.xml new file mode 100644 index 000000000000..99390cf07c74 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-sk/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Zadajte svoje heslo a pokračujte na dynamické aktualizácie systému"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamický systém je k dispozícii. Ak ho chcete začať používať, reštartujte zariadenie."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Prebieha inštalácia"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Nepodarilo sa nainštalovať"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Obrázok sa nepodarilo overiť. Prerušte inštaláciu."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Momentálne je spustený dynamický systém. Ak chcete používať pôvodnú verziu Androidu, reštartujte."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Zrušiť"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Zahodiť"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Reštartovať"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reštartovať"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Zahodený dynamický systém"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nie je možné reštartovať alebo načítať dynamický systém"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-sl/strings.xml b/packages/DynamicSystemInstallationService/res/values-sl/strings.xml new file mode 100644 index 000000000000..3ffd741ea4f6 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-sl/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Vnesite geslo in nadaljujte na dinamične posodobitve sistema"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamični sistem je pripravljen. Znova zaženite napravo, da ga boste lahko začeli uporabljati."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Namestitev poteka"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Namestitev ni uspela"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Preverjanje slike ni uspelo. Prekinite namestitev."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Trenutno se izvaja dinamični sistem. Znova zaženite, če želite uporabljati prvotno različico Androida."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Prekliči"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Zavrzi"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Znova zaženi"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Znova zaženi"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je bil zavržen"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamičnega sistema ni mogoče znova zagnati ali naložiti"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-sq/strings.xml b/packages/DynamicSystemInstallationService/res/values-sq/strings.xml new file mode 100644 index 000000000000..704b512ad9ab --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-sq/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Fut fjalëkalimin tënd dhe vazhdo te përditësimet e sistemit dinamik"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Sistemi dinamik është gati. Për të nisur përdorimin e tij, rinise pajisjen."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalimi në vazhdim"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Instalimi dështoi"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Verifikimi i imazhit dështoi. Ndërprit instalimin."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Aktualisht po ekzekutohet në një sistem dinamik. Rinise për të përdorur versionin origjinal të Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Anulo"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Hiq"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Rinis"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Rinis"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistemi dinamik u hoq"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Sistemi dinamik nuk mund të rinisej ose të ngarkohej"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-sr/strings.xml b/packages/DynamicSystemInstallationService/res/values-sr/strings.xml new file mode 100644 index 000000000000..5e4540a5eff0 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-sr/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Унесите лозинку и наставите до динамичних ажурирања система"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамични систем је спреман. Да бисте почели да га користите, рестартујте уређај."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Инсталира се"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Инсталирање није успело"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Валидација слике није успела. Откажите инсталацију."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Тренутно је покренут динамични систем. Рестартујте да бисте користили оригиналну верзију Android-а."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Откажи"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Одбаци"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Рестартуј"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартуј"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамични систем је одбачен"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Рестартовање или учитавање динамичног система није успело"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-sv/strings.xml b/packages/DynamicSystemInstallationService/res/values-sv/strings.xml new file mode 100644 index 000000000000..546ffddde639 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-sv/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Ange lösenordet och fortsätt till Dynamiska systemuppdateringar"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Det dynamiska systemet är klart. Om du vill använda det startar du om enheten."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation pågår"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Installationen misslyckades"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Bildvalideringen misslyckades. Avbryt installationen."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Ett dynamiskt system körs. Om du vill använda den ursprungliga Android-versionen startar du om."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Avbryt"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Ignorera"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Starta om"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Starta om"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Det dynamiska systemet ignorerades"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Det gick inte att starta om eller läsa in det dynamiska systemet"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-sw/strings.xml b/packages/DynamicSystemInstallationService/res/values-sw/strings.xml new file mode 100644 index 000000000000..53414d5f6b0a --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-sw/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Tafadhali weka nenosiri lako na uende kwenye Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic system iko tayari. Ili uanze kuitumia, zima kisha uwashe kifaa chako."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Inasakinisha"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Imeshindwa kusakinisha"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Imeshindwa kuthibitisha picha. Ghairi usakinishaji."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Inatumia Dynamic System kwa sasa. Zima kisha uwashe ili utumie toleo halisi la Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Ghairi"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Ondoa"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Zima kisha uwashe"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Zima kisha uwashe"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Umeondoa Dynamic System"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Imeshindwa kuzima na kuwasha au kupakia Dynamic System"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ta/strings.xml b/packages/DynamicSystemInstallationService/res/values-ta/strings.xml new file mode 100644 index 000000000000..e0aaaf7458fc --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ta/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Dynamic System Updatesஸுக்குத் தொடர உங்கள் கடவுச்சொல்லை உள்ளிடவும்"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic system தயாராக உள்ளது. இதைப் பயன்படுத்தத் தொடங்க உங்கள் சாதனத்தை மீண்டும் தொடங்கவும்."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"நிறுவப்படுகிறது"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"நிறுவ முடியவில்லை"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"படத்தைச் சரிபார்க்க முடியவில்லை. நிறுவலை ரத்துசெய்யவும்."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Dynamic system தற்போது இயக்கத்தில் உள்ளது. அசல் Android பதிப்பைப் பயன்படுத்த மீண்டும் தொடங்கவும்."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ரத்துசெய்"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"நிராகரி"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"மீண்டும் தொடங்கு"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"மீண்டும் தொடங்கு"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamic system நிராகரிக்கப்பட்டது"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dynamic systemமை மீண்டும் தொடங்கவோ ஏற்றவோ முடியவில்லை"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-te/strings.xml b/packages/DynamicSystemInstallationService/res/values-te/strings.xml new file mode 100644 index 000000000000..d497630660e3 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-te/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"దయచేసి మీ పాస్వర్డ్ను ఎంటర్ చేసి, డైనమిక్ సిస్టమ్ అప్డేట్స్ను కొనసాగించండి"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"డైనమిక్ సిస్టమ్ సిద్ధంగా ఉంది. దీనిని ఉపయోగించడానికి, మీ పరికరాన్ని రీస్టార్ట్ చేయండి."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"ఇన్స్టాల్ అవుతోంది"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ఇన్స్టాల్ చేయడం విఫలమైంది"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ఇమేజ్ నిర్ధారణ విఫలమైంది. ఇన్స్టాలేషన్ను రద్దు చేయండి."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ప్రస్తుతం డైనమిక్ సిస్టమ్ రన్నవుతోంది. ఒరిజినల్ Android వెర్షన్ను ఉపయోగించడానికి రీస్టార్ట్ చేయండి."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"రద్దు చేయండి"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"విస్మరించండి"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"రీస్టార్ట్ చేయి"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"రీస్టార్ట్ చేయి"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"డైనమిక్ సిస్టమ్ విస్మరించబడింది"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"డైనమిక్ సిస్టమ్ను రీస్టార్ట్ చేయడం లేదా లోడ్ చేయడం సాధ్యపడలేదు"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-th/strings.xml b/packages/DynamicSystemInstallationService/res/values-th/strings.xml new file mode 100644 index 000000000000..786324f57488 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-th/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"โปรดป้อนรหัสผ่านแล้วไปที่ \"อัปเดตระบบแบบไดนามิก\""</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ระบบแบบไดนามิกพร้อมแล้ว โปรดรีสตาร์ทอุปกรณ์เพื่อเริ่มใช้"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"กำลังติดตั้ง"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"ติดตั้งไม่สำเร็จ"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"ตรวจสอบรูปภาพไม่สำเร็จ ล้มเลิกการติดตั้ง"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ปัจจุบันใช้ระบบแบบไดนามิกอยู่ รีสตาร์ทเพื่อใช้ Android เวอร์ชันดั้งเดิม"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ยกเลิก"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"ยกเลิก"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"รีสตาร์ท"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"รีสตาร์ท"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ยกเลิกระบบแบบไดนามิกแล้ว"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"รีสตาร์ทหรือโหลดระบบแบบไดนามิกไม่ได้"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-tl/strings.xml b/packages/DynamicSystemInstallationService/res/values-tl/strings.xml new file mode 100644 index 000000000000..df39f7b1886a --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-tl/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Pakilagay ang iyong password at ipagpatuloy ang Dynamic System Updates"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Handa na ang dynamic system. Para simulang gamitin ito, i-restart ang iyong device."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Ini-install"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Hindi na-install"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Hindi na-validate ang image. I-abort ang pag-install."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Kasalukuyang pinapatakbo ang dynamic system. Mag-restart para gamitin ang orihinal na Android na bersyon."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Kanselahin"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"I-discard"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"I-restart"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"I-restart"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Na-discard ang dynamic system"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Hindi ma-restart o ma-load ang dynamic system"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-tr/strings.xml b/packages/DynamicSystemInstallationService/res/values-tr/strings.xml new file mode 100644 index 000000000000..1446f9632456 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-tr/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Lütfen şifrenizi girip Dinamik Sistem Güncellemesi\'ne gidin"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamik sistem hazır. Kullanmaya başlamak için cihazınızı yeniden başlatın."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Yükleme devam ediyor"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Yükleme başarısız oldu"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Resim doğrulanamadı. Yüklemeyi iptal edin."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Şu anda dinamik sistem çalıştırılıyor. Orijinal Android sürümünü kullanmak için cihazı yeniden başlatın."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"İptal"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Sil"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Yeniden başlat"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Yeniden başlat"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamik sistem silindi"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamik sistem yeniden başlatılamıyor veya yüklenemiyor"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-uk/strings.xml b/packages/DynamicSystemInstallationService/res/values-uk/strings.xml new file mode 100644 index 000000000000..9a44d9764014 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-uk/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Введіть пароль і перейдіть до Динамічних оновлень системи"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Динамічна система готова. Щоб перейти до неї, перезапустіть пристрій."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Триває встановлення"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Не вдалося встановити"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Не вдалося перевірити образ. Встановлення скасовано."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Запущено динамічну систему. Перезапустіть пристрій, щоб повернутися до попередньої версії Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Скасувати"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Видалити"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Перезапустити"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Перезапустити"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамічну систему видалено"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не вдається перезапустити пристрій або завантажити динамічну систему"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-ur/strings.xml b/packages/DynamicSystemInstallationService/res/values-ur/strings.xml new file mode 100644 index 000000000000..48dddbea3281 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-ur/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"براہ کرم اپنا پاس ورڈ درج کریں اور ڈائنیمک سسٹم اپ ڈیٹس پر جائیں"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"ڈائنیمک سسٹم تیار ہے۔ اس کا استعمال شروع کرنے کے لیے، اپنا آلہ ری سٹارٹ کریں۔"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"انسٹال جاری ہے"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"انسٹال ناکام ہو گیا"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"تصویر کی توثیق ناکام ہو گئی۔ انسٹالیشن منسوخ کریں-"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"فی الحال ہم ایک ڈائنیمک سسٹم چلا رہے ہیں۔ Android کا اصل ورژن استعمال کرنے کے لیے ری سٹارٹ کریں۔"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"منسوخ کریں"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"مسترد کریں"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ری سٹارٹ کریں"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ری سٹارٹ کریں"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"مسترد کردہ ڈائنیمک سسٹم"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ڈائنیمک سسٹم کو ری سٹارٹ یا لوڈ نہیں کر سکتے"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-uz/strings.xml b/packages/DynamicSystemInstallationService/res/values-uz/strings.xml new file mode 100644 index 000000000000..3f0227c1c383 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-uz/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Parolni kiriting va dinamik tizim yangilanishlarini davom ettiring"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Dinamik tizim tayyor. Foydalanishni boshlash uchun qurilmani qayta ishga tushiring."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Oʻrnatilmoqda"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Oʻrnatilmadi"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Rasm tekshiruvi amalga oshmadi Oʻrnatishni bekor qilish."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Hozirda dinamik tizim ishga tushirilgan. Asl Android versiyasidan foydlanish uchun qayta ishga tushiring."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Bekor qilish"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Bekor qilish"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Boshidan"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Boshidan"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamik tizim bekor qilindi"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamik tizim qayta ishga tushmadi yoki yuklanmadi"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-vi/strings.xml b/packages/DynamicSystemInstallationService/res/values-vi/strings.xml new file mode 100644 index 000000000000..18c051c893f8 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-vi/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Vui lòng nhập mật khẩu và tiếp tục dùng Bản cập nhật hệ thống động"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Hệ thống động đã sẵn sàng. Để bắt đầu sử dụng hệ thống này, hãy khởi động lại thiết bị của bạn."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Đang cài đặt"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Không cài đặt được"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Không xác thực được hình ảnh. Hủy cài đặt."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Thiết bị đang chạy một hệ thống động. Hãy khởi động lại để sử dụng Android phiên bản gốc."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Hủy"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Hủy"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Khởi động lại"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Khởi động lại"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Đã hủy hệ thống động"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Không thể khởi động lại hoặc tải hệ thống động"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000000..b41d4e2bf912 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"请输入您的密码,以便继续使用动态系统更新"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"动态系统已准备就绪。重启您的设备即可开始使用动态系统。"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"正在安装"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"安装失败"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"图片验证失败。安装将中止。"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"目前正在运行动态系统。需重启才能使用原 Android 版本。"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"取消"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"舍弃"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"重启"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"重启"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"已舍弃动态系统"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"无法重启或加载动态系统"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000000..c830dae24e97 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"請輸入密碼,以使用「動態系統更新」"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"動態系統已可供使用。如要開始使用,請重新啟動裝置。"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"安裝中"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"無法安裝"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"圖片驗證失敗,系統將取消安裝。"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"系統目前正在執行動態系統。如要使用原本的 Android 版本,請重新啟動裝置。"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"取消"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"捨棄"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"重新啟動"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"重新啟動"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"已捨棄動態系統"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"無法重新啟動或載入動態系統"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000000..e43c0f2b08bb --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"請輸入密碼,以便繼續使用動態系統更新"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"動態系統已可供使用。如要開始使用,請重新啟動裝置。"</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"安裝中"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"無法安裝"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"圖片驗證失敗,系統將取消安裝作業。"</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"系統目前正在執行動態系統。如要使用原本的 Android 版本,請重新啟動裝置。"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"取消"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"捨棄"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"重新啟動"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"重新啟動"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"已捨棄動態系統"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"無法重新啟動或載入動態系統"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values-zu/strings.xml b/packages/DynamicSystemInstallationService/res/values-zu/strings.xml new file mode 100644 index 000000000000..4a48444cb9a0 --- /dev/null +++ b/packages/DynamicSystemInstallationService/res/values-zu/strings.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="keyguard_description" msgid="8582605799129954556">"Sicela ufake iphasiwedi yakho uphinde uqhubekele Ekubuyekezweni Kohlole Okunhlobonhlobo"</string> + <string name="notification_install_completed" msgid="6252047868415172643">"Uhlole Okunhlobonhlobo kulungile. Ukuze uqale ukuyisebenzisa, qalisa kabusha idivayisi yakho."</string> + <string name="notification_install_inprogress" msgid="7383334330065065017">"Ukufaka kuyaqhubeka"</string> + <string name="notification_install_failed" msgid="4066039210317521404">"Ukufaka kwehlulekile"</string> + <string name="notification_image_validation_failed" msgid="2720357826403917016">"Ukuqinisekiswa kwesithombe kuhlulekile. Yekisa ukufakwa."</string> + <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Manje iqalisa uhlole olunhlobonhlobo. Qalisa kabusha ukuze usebenzise inguqulo yangempela ye-Android."</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"Khansela"</string> + <string name="notification_action_discard" msgid="1817481003134947493">"Lahla"</string> + <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Qala kabusha"</string> + <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Qala kabusha"</string> + <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Kulahlwe uhlole olunhlobonhlobo"</string> + <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Ayikwazi ukuqalisa kabusha noma ukulayisha uhlole olunhlobonhlobo"</string> +</resources> diff --git a/packages/DynamicSystemInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml index e124be605cc7..719fc73bd225 100644 --- a/packages/DynamicSystemInstallationService/res/values/strings.xml +++ b/packages/DynamicSystemInstallationService/res/values/strings.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <!-- application name [CHAR LIMIT=32] --> + <!-- application name [DO NOT TRANSLATE] --> <string name="app_name">Dynamic System Updates</string> - <!-- notification channel name [CHAR LIMIT=32] --> + <!-- notification channel name [DO NOT TRANSLATE] --> <string name="notification_channel_name">Dynamic System Updates</string> - <!-- password page title [CHAR LIMIT=32] --> + <!-- password page title [DO NOT TRANSLATE] --> <string name="keyguard_title">Dynamic System Updates</string> <!-- password page description [CHAR LIMIT=128] --> @@ -23,19 +23,19 @@ <!-- Displayed on notification: We are running in Dynamic System [CHAR LIMIT=128] --> <string name="notification_dynsystem_in_use">Currently running a dynamic system. Restart to use the original Android version.</string> - <!-- Action on notification: Cancel installation [CHAR LIMIT=16] --> + <!-- Action on notification: Cancel installation [CHAR LIMIT=24] --> <string name="notification_action_cancel">Cancel</string> - <!-- Action on notification: Discard installation [CHAR LIMIT=16] --> + <!-- Action on notification: Discard installation [CHAR LIMIT=24] --> <string name="notification_action_discard">Discard</string> - <!-- Action on notification: Restart to Dynamic System [CHAR LIMIT=16] --> + <!-- Action on notification: Restart to Dynamic System [CHAR LIMIT=24] --> <string name="notification_action_reboot_to_dynsystem">Restart</string> - <!-- Action on notification: Restart to original Android version [CHAR LIMIT=16] --> + <!-- Action on notification: Restart to original Android version [CHAR LIMIT=24] --> <string name="notification_action_reboot_to_origin">Restart</string> - <!-- Toast when installed Dynamic System is discarded [CHAR LIMIT=64] --> + <!-- Toast when installed Dynamic System is discarded [CHAR LIMIT=128] --> <string name="toast_dynsystem_discarded">Discarded dynamic system</string> - <!-- Toast when we fail to launch into Dynamic System [CHAR LIMIT=64] --> + <!-- Toast when we fail to launch into Dynamic System [CHAR LIMIT=128] --> <string name="toast_failed_to_reboot_to_dynsystem">Can\u2019t restart or load dynamic system</string> <!-- URL of Dynamic System Key Revocation List [DO NOT TRANSLATE] --> diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index f1ec606243c4..83319cf788c2 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -577,8 +577,11 @@ public class ExternalStorageProvider extends FileSystemProvider { public Cursor querySearchDocuments(String rootId, String[] projection, Bundle queryArgs) throws FileNotFoundException { final File parent; + synchronized (mRootsLock) { - parent = mRoots.get(rootId).path; + RootInfo root = mRoots.get(rootId); + parent = root.visiblePath != null ? root.visiblePath + : root.path; } return querySearchDocuments(parent, projection, Collections.emptySet(), queryArgs); diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml index dffaba510dff..30f6a21efe8b 100644 --- a/packages/PackageInstaller/res/values-ne/strings.xml +++ b/packages/PackageInstaller/res/values-ne/strings.xml @@ -22,30 +22,30 @@ <string name="cancel" msgid="1018267193425558088">"रद्द गर्नुहोस्"</string> <string name="installing" msgid="4921993079741206516">"स्थापना गर्दै…"</string> <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> स्थापना गर्दै…"</string> - <string name="install_done" msgid="5987363587661783896">"अनुप्रयोग स्थापना गरियो।"</string> - <string name="install_confirm_question" msgid="8176284075816604590">"तपाईं यो अनुप्रयोग स्थापना गर्न चाहनुहुन्छ?"</string> + <string name="install_done" msgid="5987363587661783896">"एप स्थापना गरियो।"</string> + <string name="install_confirm_question" msgid="8176284075816604590">"तपाईं यो एप स्थापना गर्न चाहनुहुन्छ?"</string> <string name="install_confirm_question_update" msgid="7942235418781274635">"तपाईं यो पहिलेदेखि नै विद्यमान अनुप्रयोगको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string> <string name="install_confirm_question_update_system" msgid="4713001702777910263">"तपाईं यो अन्तर्निर्मित अनुप्रयोगको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string> - <string name="install_failed" msgid="5777824004474125469">"अनुप्रयोग स्थापना गरिएन।"</string> + <string name="install_failed" msgid="5777824004474125469">"एप स्थापना गरिएन।"</string> <string name="install_failed_blocked" msgid="8512284352994752094">"यो प्याकेज स्थापना गर्ने क्रममा अवरोध गरियो।"</string> - <string name="install_failed_conflict" msgid="3493184212162521426">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग विद्यमान प्याकेजसँग मेल खाँदैन।"</string> - <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको ट्याब्लेटसँग मिल्दो छैन।"</string> - <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"यो अनुप्रयोग तपाईंको TV सँग मिल्दो छैन।"</string> - <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको फोनसँग मिल्दो छैन।"</string> - <string name="install_failed_invalid_apk" msgid="8581007676422623930">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग अमान्य जस्तो देखिन्छ।"</string> + <string name="install_failed_conflict" msgid="3493184212162521426">"प्याकेजका रूपमा स्थापना नगरिएको एप विद्यमान प्याकेजसँग मेल खाँदैन।"</string> + <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"एपका रूपमा स्थापना नगरिएको एप तपाईंको ट्याब्लेटसँग मिल्दो छैन।"</string> + <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"यो एप तपाईंको TV सँग मिल्दो छैन।"</string> + <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"एपका रूपमा स्थापना नगरिएको एप तपाईंको फोनसँग मिल्दो छैन।"</string> + <string name="install_failed_invalid_apk" msgid="8581007676422623930">"प्याकेजका रूपमा स्थापना नगरिएको एप अमान्य जस्तो देखिन्छ।"</string> <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"तपाईंको ट्याब्लेटमा <xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना गर्न सकिएन।"</string> <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"तपाईंको TV मा <xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना गर्न सकिएन।"</string> <string name="install_failed_msg" product="default" msgid="6484461562647915707">"तपाईंको फोनमा <xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना गर्न सकिएन।"</string> <string name="launch" msgid="3952550563999890101">"खोल्नुहोस्"</string> <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"तपाईंका प्रशासकले अज्ञात स्रोतहरूबाट प्राप्त अनुप्रयोगहरूलाई स्थापना गर्ने अनुमति दिनुहुन्न"</string> - <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"यी प्रयोगकर्ता अज्ञात अनुप्रयोगहरू स्थापना गर्न सक्नुहुन्न"</string> - <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"यो प्रयोगकर्तालाई अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन"</string> + <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"यी प्रयोगकर्ता अज्ञात एपहरू स्थापना गर्न सक्नुहुन्न"</string> + <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"यो प्रयोगकर्तालाई एपहरू स्थापना गर्ने अनुमति छैन"</string> <string name="ok" msgid="7871959885003339302">"ठिक छ"</string> <string name="manage_applications" msgid="5400164782453975580">"एपको प्रबन्ध गर्नु…"</string> <string name="out_of_space_dlg_title" msgid="4156690013884649502">"खाली ठाउँ छैन"</string> <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना गर्न सकिएन। केही ठाउँ खाली गरेर फेरि प्रयास गर्नुहोस्।"</string> - <string name="app_not_found_dlg_title" msgid="5107924008597470285">"अनुप्रयोग फेला परेन"</string> - <string name="app_not_found_dlg_text" msgid="5219983779377811611">"स्थापना गरिएका अनुप्रयोगहरूको सूचीमा उक्त अनुप्रयोग भेटिएन।"</string> + <string name="app_not_found_dlg_title" msgid="5107924008597470285">"एप फेला परेन"</string> + <string name="app_not_found_dlg_text" msgid="5219983779377811611">"स्थापना गरिएका एपहरूको सूचीमा उक्त एप भेटिएन।"</string> <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"अनुमति छैन"</string> <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"हालका प्रयोगकर्तालाई यो स्थापना रद्द गर्ने कार्य गर्ने अनुमति छैन।"</string> <string name="generic_error_dlg_title" msgid="5863195085927067752">"त्रुटि"</string> @@ -54,7 +54,7 @@ <string name="uninstall_update_title" msgid="824411791011583031">"अद्यावधिकको स्थापना रद्द गर्नु…"</string> <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्न अनुप्रयोगको अंश हो:"</string> <string name="uninstall_application_text" msgid="3816830743706143980">"तपाईं यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ?"</string> - <string name="uninstall_application_text_all_users" msgid="575491774380227119">"तपाईं "<b>"सबै"</b>" प्रयोगकर्ताका लागि यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ? यन्त्रका "<b>"सबै"</b>" प्रयोगकर्ताहरूबाट उक्त अनुप्रयोग र यसको डेटा हटाइने छ।"</string> + <string name="uninstall_application_text_all_users" msgid="575491774380227119">"तपाईं "<b>"सबै"</b>" प्रयोगकर्ताका लागि यो एपको स्थापना रद्द गर्न चाहनुहुन्छ? यन्त्रका "<b>"सबै"</b>" प्रयोगकर्ताहरूबाट उक्त एप र यसको डेटा हटाइने छ।"</string> <string name="uninstall_application_text_user" msgid="498072714173920526">"तपाईं प्रयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> का लागि यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ।"</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ। यसले यस यन्त्रका कार्य प्रोफाइल भएका लगायत सबै प्रयोगकर्ताहरूमा असर पार्छ।"</string> @@ -70,22 +70,22 @@ <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string> <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> को यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string> <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"अन्य प्रयोगकर्ताहरूका लागि यस अनुप्रयोगको स्थापना रद्द गरे पनि केही प्रयोगकर्ता वा प्रोफाइलहरूलाई यसको आवश्यकता पर्दछ"</string> - <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"यो अनुप्रयोग तपाईंको प्रोफाइलका लागि आवश्यक छ र यसको स्थापना रद्द गर्न सकिँदैन।"</string> - <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"यो अनुप्रयोग तपाईंको यन्त्रका प्रशासकका लागि आवश्यक छ र यसको स्थापना रद्द गर्न सकिँदैन।"</string> + <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"यो एप तपाईंको प्रोफाइलका लागि आवश्यक छ र यसको स्थापना रद्द गर्न सकिँदैन।"</string> + <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"यो एप तपाईंको यन्त्रका प्रशासकका लागि आवश्यक छ र यसको स्थापना रद्द गर्न सकिँदैन।"</string> <string name="manage_device_administrators" msgid="3092696419363842816">"यन्त्रका व्यवस्थापकीय अनुप्रयोगको व्यवस्थापन गर्नु…"</string> <string name="manage_users" msgid="1243995386982560813">"प्रयोगकर्ताहरूको व्यवस्थापन गर्नुहोस्"</string> <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> को स्थापना रद्द गर्न सकिएन।"</string> <string name="Parse_error_dlg_text" msgid="1661404001063076789">"प्याकेजलाई पार्स गर्ने क्रममा समस्या भयो।"</string> <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string> <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear मा स्थापना/स्थापना रद्द गर्ने कारबाहीहरू समर्थित छैनन्।"</string> - <string name="message_staging" msgid="8032722385658438567">"अनुप्रयोग स्थापना गर्न तयारी गर्दै…"</string> + <string name="message_staging" msgid="8032722385658438567">"एप स्थापना गर्न तयारी गर्दै…"</string> <string name="app_name_unknown" msgid="6881210203354323926">"अज्ञात"</string> - <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"तपाईंको सुरक्षाका लागि, तपाईंको ट्याब्लेटलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string> - <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"तपाईंको सुरक्षाका लागि, तपाईंको TV लाई यस स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string> - <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"तपाईंको सुरक्षाका लागि, तपाईंको फोनलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string> - <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"तपाईंको फोन तथा व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको फोनमा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string> - <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"तपाईंको ट्याब्लेट तथा व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको ट्याब्लेटमा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string> - <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"तपाईंको TV तथा व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको TV मा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string> + <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"तपाईंको सुरक्षाका लागि, तपाईंको ट्याब्लेटलाई यो स्रोतबाट प्राप्त हुने अज्ञात एपहरू स्थापना गर्ने अनुमति छैन।"</string> + <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"तपाईंको सुरक्षाका लागि, तपाईंको TV लाई यस स्रोतबाट प्राप्त हुने अज्ञात एपहरू स्थापना गर्ने अनुमति छैन।"</string> + <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"तपाईंको सुरक्षाका लागि, तपाईंको फोनलाई यो स्रोतबाट प्राप्त हुने अज्ञात एपहरू स्थापना गर्ने अनुमति छैन।"</string> + <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"तपाईंको फोन तथा व्यक्तिगत डेटा अज्ञात एपहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो एप स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको फोनमा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string> + <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"तपाईंको ट्याब्लेट तथा व्यक्तिगत डेटा अज्ञात एपहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो एप स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको ट्याब्लेटमा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string> + <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"तपाईंको TV तथा व्यक्तिगत डेटा अज्ञात एपहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो एप स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको TV मा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string> <string name="anonymous_source_continue" msgid="4375745439457209366">"जारी राख्नुहोस्"</string> <string name="external_sources_settings" msgid="4046964413071713807">"सेटिङहरू"</string> <string name="wear_app_channel" msgid="1960809674709107850">"वेयर एपहरूको स्थापना/स्थापना रद्द गर्दै"</string> diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml index 8c89ce9ca0eb..b9908d299a49 100644 --- a/packages/PackageInstaller/res/values-or/strings.xml +++ b/packages/PackageInstaller/res/values-or/strings.xml @@ -87,7 +87,7 @@ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"ଅଜଣା ଆପ୍ ଦ୍ୱାରା ଆପଣଙ୍କ ଟାବଲେଟ୍ ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପ୍କୁ ଇନଷ୍ଟଲ୍ କରିବାର ଅର୍ଥ ହେଉଛି ଆପଣଙ୍କ ଟାବ୍ଲେଟ୍ରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string> <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ଅଜଣା ଆପ୍ ଦ୍ୱାରା ଆପଣଙ୍କ ଟିଭି ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପ୍କୁ ଇନଷ୍ଟଲ୍ କରିବାର ଅର୍ଥ ହେଉଛି ଆପଣଙ୍କ ଟିଭିରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string> <string name="anonymous_source_continue" msgid="4375745439457209366">"ଜାରି ରଖନ୍ତୁ"</string> - <string name="external_sources_settings" msgid="4046964413071713807">"ସେଟିଙ୍ଗ"</string> + <string name="external_sources_settings" msgid="4046964413071713807">"ସେଟିଂସ୍"</string> <string name="wear_app_channel" msgid="1960809674709107850">"ୱିଅର୍ ଆପ୍ ଇନଷ୍ଟଲ୍/ଅନଇନଷ୍ଟଲ୍ କରାଯାଉଛି"</string> <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ଆପ୍ ଇନ୍ଷ୍ଟଲ୍ କରାଯାଇଥିବା ବିଜ୍ଞପ୍ତି"</string> <string name="notification_installation_success_message" msgid="6450467996056038442">"ସଫଳତାପୂର୍ବକ ଇନ୍ଷ୍ଟଲ୍ କରାଗଲା"</string> diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml index e47aa054788d..54b44925336c 100644 --- a/packages/PrintSpooler/AndroidManifest.xml +++ b/packages/PrintSpooler/AndroidManifest.xml @@ -36,16 +36,11 @@ <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/> <uses-permission android:name="android.permission.READ_PRINT_SERVICES" /> <uses-permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS" /> + <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - <queries> - <intent> - <action android:name="android.printservice.PrintService" /> - </intent> - </queries> - <application android:allowClearUserData="true" android:label="@string/app_label" diff --git a/packages/PrintSpooler/res/values-be/strings.xml b/packages/PrintSpooler/res/values-be/strings.xml index c04756c4bdc7..15d3c78a922d 100644 --- a/packages/PrintSpooler/res/values-be/strings.xml +++ b/packages/PrintSpooler/res/values-be/strings.xml @@ -49,7 +49,7 @@ <string name="print_options_collapsed" msgid="7455930445670414332">"Параметры друку згорнуты"</string> <string name="search" msgid="5421724265322228497">"Пошук"</string> <string name="all_printers_label" msgid="3178848870161526399">"Усе прынтары"</string> - <string name="add_print_service_label" msgid="5356702546188981940">"Дадаць службу"</string> + <string name="add_print_service_label" msgid="5356702546188981940">"Дадаць сэрвіс"</string> <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Паказваецца поле пошуку"</string> <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Поле пошуку схавана"</string> <string name="print_add_printer" msgid="1088656468360653455">"Дадаць прынтар"</string> @@ -66,9 +66,9 @@ <string name="notification_channel_progress" msgid="872788690775721436">"Заданні друку, якія выконваюцца"</string> <string name="notification_channel_failure" msgid="9042250774797916414">"Заданні друку са збоямі"</string> <string name="could_not_create_file" msgid="3425025039427448443">"Не ўдалося стварыць файл"</string> - <string name="print_services_disabled_toast" msgid="9089060734685174685">"Некаторыя службы друку адключаны"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Некаторыя сэрвісы друку адключаны"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Пошук прынтараў"</string> - <string name="print_no_print_services" msgid="8561247706423327966">"Службы друку не ўключаны"</string> + <string name="print_no_print_services" msgid="8561247706423327966">"Сэрвісы друку не ўключаны"</string> <string name="print_no_printers" msgid="4869403323900054866">"Прынтараў не знойдзена"</string> <string name="cannot_add_printer" msgid="7840348733668023106">"Немагчыма дадаць прынтары"</string> <string name="select_to_add_printers" msgid="3800709038689830974">"Выберыце, каб дадаць прынтар"</string> diff --git a/packages/PrintSpooler/res/values-is/strings.xml b/packages/PrintSpooler/res/values-is/strings.xml index eb7f01d14355..a75cbfe7cf2a 100644 --- a/packages/PrintSpooler/res/values-is/strings.xml +++ b/packages/PrintSpooler/res/values-is/strings.xml @@ -49,7 +49,7 @@ <string name="print_options_collapsed" msgid="7455930445670414332">"Prentvalkostir minnkaðir"</string> <string name="search" msgid="5421724265322228497">"Leita"</string> <string name="all_printers_label" msgid="3178848870161526399">"Allir prentarar"</string> - <string name="add_print_service_label" msgid="5356702546188981940">"Bæta við þjónustu"</string> + <string name="add_print_service_label" msgid="5356702546188981940">"Bæta prentara við"</string> <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Leitarreitur sýndur"</string> <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Leitarreitur falinn"</string> <string name="print_add_printer" msgid="1088656468360653455">"Bæta við prentara"</string> diff --git a/packages/PrintSpooler/res/values-ky/strings.xml b/packages/PrintSpooler/res/values-ky/strings.xml index a7150d561db9..2f57233cc1d1 100644 --- a/packages/PrintSpooler/res/values-ky/strings.xml +++ b/packages/PrintSpooler/res/values-ky/strings.xml @@ -84,7 +84,7 @@ <string name="failed_notification_title_template" msgid="2256217208186530973">"Принтерде ката кетти: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"Принтер бөгөттөдү: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancel" msgid="4373674107267141885">"Айнуу"</string> - <string name="restart" msgid="2472034227037808749">"Кайра баштоо"</string> + <string name="restart" msgid="2472034227037808749">"Өчүрүп күйгүзүү"</string> <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер менен байланыш жок"</string> <string name="reason_unknown" msgid="5507940196503246139">"белгисиз"</string> <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> колдоносузбу?"</string> diff --git a/packages/PrintSpooler/res/values-ne/strings.xml b/packages/PrintSpooler/res/values-ne/strings.xml index 154364de4b53..d0b7a5e41dc1 100644 --- a/packages/PrintSpooler/res/values-ne/strings.xml +++ b/packages/PrintSpooler/res/values-ne/strings.xml @@ -33,11 +33,11 @@ <string name="pages_range_example" msgid="8558694453556945172">"उदाहरण १-५,८,११-१३"</string> <string name="print_preview" msgid="8010217796057763343">"प्रिन्ट पूर्वावलोकन"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"पूर्वावलोकनको लागि PDF भ्यूअर स्थापना गर्नुहोस्"</string> - <string name="printing_app_crashed" msgid="854477616686566398">"प्रिन्टिङ अनुप्रयोग क्र्यास भयो"</string> + <string name="printing_app_crashed" msgid="854477616686566398">"प्रिन्टिङ एप क्र्यास भयो"</string> <string name="generating_print_job" msgid="3119608742651698916">"प्रिन्ट कार्य निर्माण गरिँदै"</string> <string name="save_as_pdf" msgid="5718454119847596853">"PDF को रूपमा सुरक्षित गर्नुहोस्"</string> <string name="all_printers" msgid="5018829726861876202">"सबै प्रिन्टरहरू..."</string> - <string name="print_dialog" msgid="32628687461331979">"सम्वाद छाप्नुहोस्"</string> + <string name="print_dialog" msgid="32628687461331979">"सम्वाद प्रिन्ट गर्नुहोस्"</string> <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string> <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g> को <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> पृष्ठ"</string> <string name="summary_template" msgid="8899734908625669193">"सारांश, प्रतिहरू <xliff:g id="COPIES">%1$s</xliff:g> , कागज आकार <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml index f385391c8d78..86c5351e5a0a 100644 --- a/packages/PrintSpooler/res/values-or/strings.xml +++ b/packages/PrintSpooler/res/values-or/strings.xml @@ -49,10 +49,10 @@ <string name="print_options_collapsed" msgid="7455930445670414332">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ଛୋଟ କରାଯାଇଛି"</string> <string name="search" msgid="5421724265322228497">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string> <string name="all_printers_label" msgid="3178848870161526399">"ସମସ୍ତ ପ୍ରିଣ୍ଟର୍"</string> - <string name="add_print_service_label" msgid="5356702546188981940">"ସେବା ଯୋଡ଼ନ୍ତୁ"</string> + <string name="add_print_service_label" msgid="5356702546188981940">"ସେବା ଯୋଗ କରନ୍ତୁ"</string> <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ସର୍ଚ୍ଚ ବକ୍ସ ଦେଖାଯାଇଛି"</string> <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ସର୍ଚ୍ଚ ବକ୍ସ ଲୁଚି ରହିଛି"</string> - <string name="print_add_printer" msgid="1088656468360653455">"ପ୍ରିଣ୍ଟର୍ ଯୋଡ଼ନ୍ତୁ"</string> + <string name="print_add_printer" msgid="1088656468360653455">"ପ୍ରିଣ୍ଟର୍ ଯୋଗ କରନ୍ତୁ"</string> <string name="print_select_printer" msgid="7388760939873368698">"ପ୍ରିଣ୍ଟର୍ ଚୟନ କରନ୍ତୁ"</string> <string name="print_forget_printer" msgid="5035287497291910766">"ପ୍ରିଣ୍ଟର୍ ଭୁଲିଯାଆନ୍ତୁ"</string> <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868"> diff --git a/packages/SettingsLib/LayoutPreference/res/drawable/ic_swap_horiz_blue.xml b/packages/SettingsLib/LayoutPreference/res/drawable/ic_swap_horiz_blue.xml index 04de17474368..afebeba2d5ff 100644 --- a/packages/SettingsLib/LayoutPreference/res/drawable/ic_swap_horiz_blue.xml +++ b/packages/SettingsLib/LayoutPreference/res/drawable/ic_swap_horiz_blue.xml @@ -18,8 +18,9 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24"> + android:viewportHeight="24" + android:tint="?android:attr/colorAccent"> <path android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z" - android:fillColor="#4285F4"/> + android:fillColor="@android:color/white"/> </vector> diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml index e26af95395a0..42cf76173a72 100644 --- a/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml +++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="enabled_by_admin" msgid="6630472777476410137">"فعَّل المشرف هذا الإعداد."</string> + <string name="enabled_by_admin" msgid="6630472777476410137">"يفعِّل المشرف هذا الإعداد."</string> <string name="disabled_by_admin" msgid="4023569940620832713">"أوقف المشرف هذا الإعداد."</string> </resources> diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-es/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-es/strings.xml index 4a6f73f0fcef..351f16cb1a24 100644 --- a/packages/SettingsLib/RestrictedLockUtils/res/values-es/strings.xml +++ b/packages/SettingsLib/RestrictedLockUtils/res/values-es/strings.xml @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="enabled_by_admin" msgid="6630472777476410137">"Habilitada por el administrador"</string> - <string name="disabled_by_admin" msgid="4023569940620832713">"Inhabilitada por el administrador"</string> + <string name="enabled_by_admin" msgid="6630472777476410137">"Habilitado por el administrador"</string> + <string name="disabled_by_admin" msgid="4023569940620832713">"Inhabilitado por el administrador"</string> </resources> diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ja/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ja/strings.xml index 7fcdbdfa7dab..490efd099569 100644 --- a/packages/SettingsLib/RestrictedLockUtils/res/values-ja/strings.xml +++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ja/strings.xml @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="enabled_by_admin" msgid="6630472777476410137">"管理者が有効にしました"</string> - <string name="disabled_by_admin" msgid="4023569940620832713">"管理者が無効にしました"</string> + <string name="enabled_by_admin" msgid="6630472777476410137">"管理者によって有効にされています"</string> + <string name="disabled_by_admin" msgid="4023569940620832713">"管理者により無効にされています"</string> </resources> diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml index d4bac70ac4e7..9c225f92f3bb 100644 --- a/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml +++ b/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="enabled_by_admin" msgid="6630472777476410137">"प्रशासकाने सुरू केलेले"</string> + <string name="enabled_by_admin" msgid="6630472777476410137">"अॅडमिनने सुरू केलेले"</string> <string name="disabled_by_admin" msgid="4023569940620832713">"प्रशासकाने बंद केलेले"</string> </resources> diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rPT/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rPT/strings.xml index 5cf0b29e14ff..e57d1cc11a20 100644 --- a/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/RestrictedLockUtils/res/values-pt-rPT/strings.xml @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="enabled_by_admin" msgid="6630472777476410137">"Ativada pelo administrador"</string> + <string name="enabled_by_admin" msgid="6630472777476410137">"Ativado pelo administrador"</string> <string name="disabled_by_admin" msgid="4023569940620832713">"Desativada pelo administrador"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml b/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml index 6b2364d04cc6..9977138f2079 100644 --- a/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"Paramètres de recherche"</string> + <string name="search_menu" msgid="1914043873178389845">"Rechercher dans les paramètres"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-hi/strings.xml b/packages/SettingsLib/SearchWidget/res/values-hi/strings.xml index 975c320f9dba..88c38316948a 100644 --- a/packages/SettingsLib/SearchWidget/res/values-hi/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-hi/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"खोज की सेटिंग"</string> + <string name="search_menu" msgid="1914043873178389845">"सेटिंग में खोजें"</string> </resources> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 1eef0b7ccf04..7e0ff8174b81 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Sal waarskynlik hou tot omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery kan teen <xliff:g id="TIME">%1$s</xliff:g> afloop"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Meer as <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Meer as <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Foon sal dalk binnekort afgaan"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet sal dalk binnekort afgaan"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Toestel sal dalk binnekort afgaan"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index f8dcb3a68a89..391ceb7a32ea 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"እስከ <xliff:g id="TIME">%1$s</xliff:g> ገደማ መቆየት አለበት"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"እስከ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ባትሪ እስከ <xliff:g id="TIME">%1$s</xliff:g> ድረስ ሊያልቅ ይችላል"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"ከ <xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"ከ <xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"ከ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> የበለጠ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"ከ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> የበለጠ ይቀራል"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ስልኩ በቅርቡ ሊዘጋ ይችላል"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ጡባዊው በቅርቡ ሊዘጋ ይችላል"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"መሣሪያው በቅርቡ ሊዘጋ ይችላል"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index aee506175875..51eae81b8aa3 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"حتى <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"قد ينفد شحن البطارية قبل <xliff:g id="TIME">%1$s</xliff:g>."</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"سيبقى شحن البطارية أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"سيبقى شحن البطارية أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"سيبقى شحن البطارية أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"سيبقى شحن البطارية أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g>."</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"قد يتم إغلاق الهاتف قريبًا"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"قد يتم إغلاق الجهاز اللوحي قريبًا"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"قد يتم إغلاق الجهاز قريبًا"</string> @@ -515,8 +511,8 @@ <string name="alarm_template" msgid="3346777418136233330">"الساعة <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="6382760514842998629">"يوم <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"المدة"</string> - <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"الطلب في كل مرة"</string> - <string name="zen_mode_forever" msgid="3339224497605461291">"إلى أن توقف الوضع يدويًا"</string> + <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"السؤال في كل مرة"</string> + <string name="zen_mode_forever" msgid="3339224497605461291">"إلى أن يتم إيقاف الوضع"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"للتو"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"مكبر صوت الهاتف"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index bf0831983fc8..587151fdccea 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"বেটাৰি আনুমানিকভাৱে <xliff:g id="TIME">%1$s</xliff:g> লৈকে চলিব"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> পৰ্যন্ত"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g>ৰ ভিতৰত বেটাৰী শেষ হ\'ব পাৰে"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g>তকৈ কম বাকী আছে"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g>তকৈ কম বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>তকৈ বেছি বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>তকৈ বেছি বাকী আছে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ফ’নটো সোনকালে বন্ধ হৈ যাব পাৰে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"টেবলেটটো সোনকালে বন্ধ হৈ যাব পাৰে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ডিভাইচটো সোনকালে বন্ধ হৈ যাব পাৰে"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 40eb00b2396c..738480f5cae8 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> olana qədər"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batareya <xliff:g id="TIME">%1$s</xliff:g> radələrinə qədər boşala bilər"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Maksimum <xliff:g id="THRESHOLD">%1$s</xliff:g> qalıb"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Maksimum <xliff:g id="THRESHOLD">%1$s</xliff:g> qalıb (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Minimum <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Minimum <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon tezliklə sönə bilər"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planşet tezliklə sönə bilər"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Cihaz tezliklə sönə bilər"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index e9d314bd28f6..6187f93a81d4 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija će se možda isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 713c7cd8065d..6cca97da0a38 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Зараду хопіць прыблізна да <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Да <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Акумулятар разрадзіцца ў <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Засталося менш за <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Засталося менш за <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Засталося больш за <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Засталося больш за <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Тэлефон у хуткім часе выключыцца"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшэт у хуткім часе выключыцца"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Прылада ў хуткім часе выключыцца"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 57456d9a7ca6..c128f3d0a7d8 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Следва да издържи до около <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерията може да се изтощи до <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Остава(т) по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Остава(т) по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Остава(т) повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Остава(т) повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Възможно е телефонът да се изключи скоро"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Възможно е таблетът да се изключи скоро"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Възможно е устройството да се изключи скоро"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index decb3da257c1..bdc93380f31b 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"আনুমানিক <xliff:g id="TIME">%1$s</xliff:g> পর্যন্ত চলবে"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> পর্যন্ত"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ব্যাটারির চার্জ <xliff:g id="TIME">%1$s</xliff:g>-এ শেষ হয়ে যেতে পারে"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-এরও কম সময় চলবে"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-এরও কম সময় চলবে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-এরও বেশি সময় চলবে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-এরও বেশি সময় চলবে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ফোন শীঘ্রই বন্ধ হয়ে যেতে পারে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ট্যাবলেটটি শীঘ্রই বন্ধ হয়ে যেতে পারে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ডিভাইসটি শীঘ্রই বন্ধ হয়ে যেতে পারে"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 0a9d260088f1..6f9188d5ac36 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Srednja brzina"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brzo"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Istekao"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Isključen"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze…"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Trebala bi trajati otprilike do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija bi se mogla isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index ffa55afd2092..da70d3b04f38 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"És possible que la bateria s\'esgoti a les <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Temps restant superior a <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Temps restant superior a <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"És possible que el telèfon s\'apagui aviat"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"És possible que la tauleta s\'apagui aviat"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"És possible que el dispositiu s\'apagui aviat"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 504cc5eef7b5..4d071b091543 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterie se může vybít do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Zbývá více než <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Zbývá více než <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon se brzy vypne"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet se brzy vypne"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Zařízení se brzy vypne"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 2f929f788a03..ba56d32a6680 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Indtil <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Enheden løber muligvis tør for batteri inden <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen lukker muligvis snart ned"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Denne tablet lukker muligvis snart ned"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheden lukker muligvis snart ned"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 7838a0c810db..59c5b1d96eb3 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Bis <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Der Akku ist voraussichtlich um <xliff:g id="TIME">%1$s</xliff:g> leer"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Smartphone wird eventuell bald ausgeschaltet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet wird eventuell bald ausgeschaltet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Gerät wird eventuell bald ausgeschaltet"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index dcfee98eabaf..8744cb1735a9 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es posible que la batería se agote para las <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Es posible que pronto se apague el teléfono"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Es posible que pronto se apague la tablet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Es posible que pronto se apague el dispositivo"</string> @@ -455,7 +451,7 @@ <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string> - <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carga rápida"</string> + <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápido"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carga lenta"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando."</string> <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Conectado. No se puede cargar en este momento"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index e7a84751ca72..f1540e6dac87 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar hasta las <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Puede que se agote la batería sobre las <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Es posible que el teléfono se apague pronto"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Es posible que el tablet se apague pronto"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Es posible que el dispositivo se apague pronto"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index f42111d1989b..206917e0d3c2 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Peaks kestma kuni <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Kuni <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Aku võib tühjaks saada kell <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Vähem kui <xliff:g id="THRESHOLD">%1$s</xliff:g> jäänud"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Vähem kui <xliff:g id="THRESHOLD">%1$s</xliff:g> jäänud (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Rohkem kui <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Rohkem kui <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon võib peagi välja lülituda"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tahvelarvuti võib peagi välja lülituda"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Seade võib peagi välja lülituda"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 85260fe01e26..d2c2ae4dd299 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ordu honetara arte iraungo du, gutxi gorabehera: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> arte"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baliteke bateria ordu honetan agortzea: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago geratzen dira"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago geratzen dira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> baino gehiago geratzen dira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> baino gehiago geratzen dira"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Baliteke telefonoa laster itzaltzea"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Baliteke tableta laster itzaltzea"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Baliteke gailua laster itzaltzea"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 6afa8898d3b1..fba9ae5532f2 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -435,15 +435,11 @@ <string name="power_discharge_by" msgid="4113180890060388350">"باید حدوداً تا <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) شارژ داشته باشید"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"باید حدوداً تا <xliff:g id="TIME">%1$s</xliff:g> شارژ داشته باشید"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"تا <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ممکن است باتری در <xliff:g id="TIME">%1$s</xliff:g> تمام شود"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ممکن است باتری <xliff:g id="TIME">%1$s</xliff:g> تمام شود"</string> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> شارژ باقی مانده است"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"بیش از <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"بیش از <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ممکن است تلفن بهزودی خاموش شود"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ممکن است رایانه لوحی بهزودی خاموش شود"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ممکن است دستگاه بهزودی خاموش شود"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 9e1fa76341ee..969180f2fd1e 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Varaus loppuu noin <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> saakka"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Akku voi loppua <xliff:g id="TIME">%1$s</xliff:g> mennessä"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Yli <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Yli <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Puhelin voi sammua pian"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tabletti voi sammua pian"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Laite voi sammua pian"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index bc113cd263e3..51f79baea6bd 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -218,7 +218,7 @@ <string name="adb_paired_devices_title" msgid="5268997341526217362">"Appareils associés"</string> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Actuellement connecté"</string> <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Renseignements sur l\'appareil"</string> - <string name="adb_device_forget" msgid="193072400783068417">"Oublier"</string> + <string name="adb_device_forget" msgid="193072400783068417">"Supprimer"</string> <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Empreinte digitale d\'appareil : <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string> <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Échec de la connexion"</string> <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Vérifiez que <xliff:g id="DEVICE_NAME">%1$s</xliff:g> est connecté au bon réseau"</string> @@ -435,7 +435,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La pile risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La pile risque d\'être épuisée d\'ici <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index c2a8d496d9eb..5e6ee8691377 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batterie risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Le téléphone va bientôt s\'éteindre"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"La tablette va bientôt s\'éteindre"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"L\'appareil va bientôt s\'éteindre"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 2a6bcfc51c3a..caa1f1bf171e 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -435,15 +435,11 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Debería durar aproximadamente ata a seguinte hora: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente ata a seguinte hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Ata: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A batería pode esgotarse á seguinte hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A batería pode esgotarse a esta hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tempo restante: máis de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo restante: máis de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"O teléfono pode apagarse en breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"A tableta pode apagarse en breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"O dispositivo pode apagarse en breve"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index f6a237434413..5bfe3a3f9e5f 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"લગભગ <xliff:g id="TIME">%1$s</xliff:g> સુધી ચાલવી જોઈએ"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> સુધી"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"બૅટરી <xliff:g id="TIME">%1$s</xliff:g> સુધીમાં પૂરી થઈ શકે છે"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> કરતાં ઓછી બાકી છે"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> કરતાં ઓછી (<xliff:g id="LEVEL">%2$s</xliff:g>) બાકી છે"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> કરતાં વધુ (<xliff:g id="LEVEL">%2$s</xliff:g>) બાકી છે"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> કરતાં વધુ બાકી છે"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ફોન થોડીક જ વારમાં બંધ થઈ શકે છે"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ટૅબ્લેટ થોડીક જ વારમાં બંધ થઈ શકે છે"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ડિવાઇસ થોડીક જ વારમાં બંધ થઈ શકે છે"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index b084123da139..999e344812b4 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -161,7 +161,7 @@ <string name="tts_default_pitch_title" msgid="6988592215554485479">"पिच"</string> <string name="tts_default_pitch_summary" msgid="9132719475281551884">"कृत्रिम बोली के लहजे को प्रभावित करता है"</string> <string name="tts_default_lang_title" msgid="4698933575028098940">"भाषा"</string> - <string name="tts_lang_use_system" msgid="6312945299804012406">"सिस्टम भाषा का उपयोग करें"</string> + <string name="tts_lang_use_system" msgid="6312945299804012406">"सिस्टम की भाषा का इस्तेमाल करें"</string> <string name="tts_lang_not_selected" msgid="7927823081096056147">"भाषा नहीं चुनी गई है"</string> <string name="tts_default_lang_summary" msgid="9042620014800063470">"बोले गए लेख के लिए भाषा-विशिष्ट ध्वनि सेट करता है"</string> <string name="tts_play_example_title" msgid="1599468547216481684">"एक उदाहरण सुनें"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"बैटरी करीब <xliff:g id="TIME">%1$s</xliff:g> तक चलेगी"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> तक"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"बैटरी <xliff:g id="TIME">%1$s</xliff:g> तक खत्म हो जाएगी"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम बैटरी बची है"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> से ज़्यादा चलने लायक बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> से ज़्यादा चलने लायक बैटरी बची है"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"फ़ोन जल्द ही बंद हो सकता है"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"टैबलेट जल्द ही बंद हो सकता है"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"डिवाइस जल्द ही बंद हो सकता है"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 115fef8c7b27..391d62c02e40 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Trebala bi trajati do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija bi se mogla isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon bi se uskoro mogao isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet bi se uskoro mogao isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj bi se uskoro mogao isključiti"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index a223b4d03b2a..02a7b67c2f6b 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Eddig: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Az akkumulátor lemerülhet a következő időpontig: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Több mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Több mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Előfordulhat, hogy a telefon hamarosan kikapcsol"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Előfordulhat, hogy a táblagép hamarosan kikapcsol"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Előfordulhat, hogy az eszköz hamarosan kikapcsol"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 8d40abc9ab72..8b7679a4b54c 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Լիցքը պետք է որ բավականացնի մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Մարտկոցի լիցքը կարող է սպառվել մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Հեռախոսը շուտով կանջատվի"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Պլանշետը շուտով կանջատվի"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Սարքը շուտով կանջատվի"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index d925df3a8239..543403a66735 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Miðlungshratt"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Hratt"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Mjög hratt"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Útrunninn"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Útrunnin"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Aftengt"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Aftengist…"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ætti að endast til u.þ.b. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Til klukkan <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Rafhlaðan gæti tæmst kl. <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Meira en <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Meira en <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Síminn gæti slökkt á sér fljótlega"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Spjaldtölvan gæti slökkt á sér fljótlega"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Tækið gæti slökkt á sér fljótlega"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 3f385974bb9e..dd597d02005f 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Veloce"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Molto veloce"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Scaduto"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Scaduta"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Disconnesso"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione..."</string> @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Scegli profilo"</string> <string name="category_personal" msgid="6236798763159385225">"Personali"</string> - <string name="category_work" msgid="4014193632325996115">"Lavoro"</string> + <string name="category_work" msgid="4014193632325996115">"Di lavoro"</string> <string name="development_settings_title" msgid="140296922921597393">"Opzioni sviluppatore"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Attiva Opzioni sviluppatore"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Imposta opzioni per lo sviluppo di applicazioni"</string> @@ -435,15 +435,11 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Ora stimata esaurimento batteria: <xliff:g id="TIME">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"Ora stimata esaurimento batteria: <xliff:g id="TIME">%1$s</xliff:g> circa"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Fino alle ore <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batteria potrebbe esaurirsi entro <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batteria potrebbe esaurirsi entro le <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Il telefono potrebbe spegnersi a breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Il tablet potrebbe spegnersi a breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Il dispositivo potrebbe spegnersi a breve"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 53f82eba9c39..a7862a15a520 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"אמורה להחזיק מעמד בערך עד <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"עד <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ייתכן שהסוללה תתרוקן עד <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"יש פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"יש פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"יש יותר מ-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"יש יותר מ-<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"הטלפון עלול להיכבות בקרוב"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"הטאבלט עלול להיכבות בקרוב"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"המכשיר עלול להיכבות בקרוב"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 2f91ea639263..9947b18ec5da 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"電池が切れる推定時刻: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> まで"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> 頃に電池がなくなります"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>未満"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)未満"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"残り時間: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)以上"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"残り時間: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>以上"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"スマートフォンの電源がもうすぐ切れます"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"タブレットの電源がもうすぐ切れます"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"デバイスの電源がもうすぐ切れます"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 965a76dad9de..5240b0c54978 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -435,7 +435,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"უნდა იმუშაოს დაახლოებით <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)-მდე"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"უნდა იმუშაოს დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>-მდე"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>-მდე"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ბატარეა შესაძლოა ამოიწუროს <xliff:g id="TIME">%1$s</xliff:g>-ისთვის"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ბატარეა შესაძლოა ამოიწუროს <xliff:g id="TIME">%1$s</xliff:g>-მდე"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"დარჩა <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"დარჩა <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"დარჩა <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ზე მეტი (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 5aec86bc5705..84d0bb65c25a 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> дейін жетеді"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> дейін"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея заряды сағат <xliff:g id="TIME">%1$s</xliff:g> қарай бітуі мүмкін."</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Ең азы <xliff:g id="THRESHOLD">%1$s</xliff:g> қалды"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Ең азы <xliff:g id="THRESHOLD">%1$s</xliff:g> қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Ең көбі <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Ең көбі <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон көп ұзамай өшуі мүмкін"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет көп ұзамай өшуі мүмкін"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Құрылғы көп ұзамай өшуі мүмкін"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index aa5205264942..f1e42db85619 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"មធ្យម"</string> <string name="speed_label_fast" msgid="2677719134596044051">"លឿន"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"លឿនខ្លាំង"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ផុតកំណត់"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"បានផុតកំណត់"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"បានផ្ដាច់"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"កំពុងផ្ដាច់…"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"គួរតែអាចប្រើបានរហូតដល់ម៉ោងប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"រហូតដល់ម៉ោង <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"អាចនឹងអស់ថ្មត្រឹមម៉ោង <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"នៅសល់តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"នៅសល់តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"នៅសល់ច្រើនជាង <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"នៅសល់ច្រើនជាង <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ទូរសព្ទអាចនឹងបិទក្នុងពេលបន្តិចទៀត"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ថេប្លេតអាចនឹងបិទក្នុងពេលបន្តិចទៀត"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ឧបករណ៍អាចនឹងបិទក្នុងពេលបន្តិចទៀត"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index aece31fb1ef6..5e60928c9290 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"<xliff:g id="TIME">%1$s</xliff:g> ಸಮಯದವರೆಗೆ ಫೋನ್ ರನ್ ಆಗಬೇಕು"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> ರವರೆಗೆ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> ಗಳಲ್ಲಿ ಬ್ಯಾಟರಿ ಮುಕ್ತಾಯವಾಗಬಹುದು"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ಕ್ಕಿಂತ ಕಡಿಮೆ ಸಮಯ ಉಳಿದಿದೆ"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ಕ್ಕಿಂತ ಕಡಿಮೆ ಸಮಯ ಉಳಿದಿದೆ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಸಮಯ ಉಳಿದಿದೆ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಸಮಯ ಉಳಿದಿದೆ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ಫೋನ್ ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ಟ್ಯಾಬ್ಲೆಟ್ ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ಸಾಧನವು ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 9dbeb45cea8e..7c20c94b0ea3 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"대략 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>까지"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"예상 배터리 종료 시간: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> 이상 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> 이상 남음"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"휴대전화가 곧 종료될 수 있음"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"태블릿이 곧 종료될 수 있음"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"기기가 곧 종료될 수 있음"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 66c5c4fb09f5..8ec5f3ac661c 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Орто"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Ылдам"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Абдан ылдам"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мөөнөтү бүткөн"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Эскирип калган"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылган"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылууда…"</string> @@ -76,7 +76,7 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Туташып турат (телефониясыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Туташып турат (медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Туташып турат (телефониясыз же медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Жигердүү, батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Иштеп жатат, батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Активдүү, сол: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, оң: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Сол: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, оң: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Болжол менен саат <xliff:g id="TIME">%1$s</xliff:g> өчөт"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> чейин"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея <xliff:g id="TIME">%1$s</xliff:g> отуруп калышы мүмкүн"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> азыраак калды"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> азыраак калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> көбүрөөк калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> көбүрөөк калды"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон бир аздан кийин өчүп калышы мүмкүн"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет бир аздан кийин өчүп калышы мүмкүн"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Түзмөк бир аздан кийин өчүп калышы мүмкүн"</string> @@ -458,7 +454,7 @@ <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Жай кубатталууда"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"Кубат алган жок"</string> - <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Сайылып турат, учурда кубаттоо мүмкүн эмес"</string> + <string name="battery_info_status_not_charging" msgid="8330015078868707899">"сайылып турат, бирок кубатталган жок"</string> <string name="battery_info_status_full" msgid="4443168946046847468">"Толук"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Администратор тарабынан көзөмөлдөнөт"</string> <string name="disabled" msgid="8017887509554714950">"Өчүрүлгөн"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 4772124307f6..cc43d5aeff9b 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Turėtų išsikrauti maždaug po <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Iki <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Akumuliatoriaus energija gali išsekti <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Liko daugiau nei <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Liko daugiau nei <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonas netrukus gali būti išjungtas"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planšetinis komp. netrukus gali būti išjungtas"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Įrenginys netrukus gali būti išjungtas"</string> diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml index 90956ad99e9e..85ca0cb0077c 100644 --- a/packages/SettingsLib/res/values-mk/arrays.xml +++ b/packages/SettingsLib/res/values-mk/arrays.xml @@ -26,7 +26,7 @@ <item msgid="6050951078202663628">"Се поврзува..."</item> <item msgid="8356618438494652335">"Автентицирање..."</item> <item msgid="2837871868181677206">"Добивање ИП адреса..."</item> - <item msgid="4613015005934755724">"Поврзана"</item> + <item msgid="4613015005934755724">"Поврзано"</item> <item msgid="3763530049995655072">"Суспендирана"</item> <item msgid="7852381437933824454">"Се исклучува..."</item> <item msgid="5046795712175415059">"Исклучено"</item> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index f61c44cd4440..156d941a7de7 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> വരെ നീണ്ടുനിൽക്കേണ്ടതാണ്"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> വരെ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> ആവുമ്പോഴേക്ക് ബാറ്ററി തീർന്നേക്കാം"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> എന്നതിൽ കുറവ് സമയം ശേഷിക്കുന്നു"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> എന്നതിൽ കുറവ് സമയം ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ൽ കൂടുതൽ ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ൽ കൂടുതൽ ശേഷിക്കുന്നു"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ഫോൺ ഉടൻ ഷട്ട് ഡൗൺ ആയേക്കാം"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ടാബ്ലെറ്റ് ഉടൻ ഷട്ട് ഡൗൺ ആയേക്കാം"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ഉപകരണം ഉടൻ ഷട്ട് ഡൗൺ ആയേക്കാം"</string> diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml index ce868af26bc9..c5e87bcf3945 100644 --- a/packages/SettingsLib/res/values-mn/arrays.xml +++ b/packages/SettingsLib/res/values-mn/arrays.xml @@ -40,7 +40,7 @@ <item msgid="8339720953594087771">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> руу холбогдож байна…"</item> <item msgid="3028983857109369308">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>-тай гэрчилж байна…"</item> <item msgid="4287401332778341890">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>-с IP хаягийг авч байна…"</item> - <item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> руу холбогдсон"</item> + <item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>-д холбогдсон"</item> <item msgid="7445993821842009653">"Түр хаасан"</item> <item msgid="1175040558087735707">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>-с салгагдаж байна…"</item> <item msgid="699832486578171722">"Салгагдсан"</item> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 33806451220b..249489ed6140 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> хүртэл барих ёстой"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> хүртэл"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарейн цэнэг <xliff:g id="TIME">%1$s</xliff:g> гээд дуусаж болзошгүй"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага үлдсэн"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-с их үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-с их үлдсэн"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Утас удахгүй унтарч болзошгүй"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет удахгүй унтарч болзошгүй"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Төхөөрөмж удахгүй унтарч болзошгүй"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index b382f75ac5ae..b2e4c0a77d52 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"सुमारे <xliff:g id="TIME">%1$s</xliff:g> पर्यंत टिकावी"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> पर्यंत"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> वाजेपर्यंत बॅटरी संपू शकते"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> पेक्षा कमी शिल्लक आहे"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> पेक्षा कमी (<xliff:g id="LEVEL">%2$s</xliff:g>) शिल्लक आहे"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> पेक्षा जास्त (<xliff:g id="LEVEL">%2$s</xliff:g>) शिल्लक आहे"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> पेक्षा जास्त शिल्लक आहे"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"फोन लवकरच बंद होऊ शकतो"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"टॅबलेट लवकरच बंद होऊ शकतो"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"डिव्हाइस लवकरच बंद होऊ शकते"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index f34e2b81498d..fa36975559b6 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Seharusnya boleh digunakan hingga kira-kira <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateri mungkin habis menjelang <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g> lagi"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Lebih daripada <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Lebih daripada <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon mungkin ditutup tidak lama lagi"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet mungkin ditutup tidak lama lagi"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Peranti mungkin ditutup tidak lama lagi"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 3f3877110f14..e374d65f21a7 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Skal vare til omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Til <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet kan gå tomt <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mer enn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Mer enn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen slås kanskje av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Nettbrettet slås kanskje av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheten slås kanskje av snart"</string> diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml index 5d79e80608d0..2895a02cbae4 100644 --- a/packages/SettingsLib/res/values-ne/arrays.xml +++ b/packages/SettingsLib/res/values-ne/arrays.xml @@ -40,7 +40,7 @@ <item msgid="8339720953594087771">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>सँग जडान हुँदै..."</item> <item msgid="3028983857109369308">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>को साथ प्रमाणित गर्दै…"</item> <item msgid="4287401332778341890">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>बाट IP ठेगाना प्राप्त गर्दै…"</item> - <item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>सँग जडित"</item> + <item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> मा जोडिएको छ"</item> <item msgid="7445993821842009653">"निलम्बित"</item> <item msgid="1175040558087735707">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>बाट विच्छेदन गर्दै..."</item> <item msgid="699832486578171722">"विच्छेदन भएको"</item> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 9a839fa0f32a..870a6d169f11 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -251,8 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ताररहित प्रदर्शन प्रमाणीकरण"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi-Fi वर्बोज लग सक्षम पार्नुहोस्"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi स्क्यान थ्रोटलिङ"</string> - <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> - <skip /> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi द्वारा परिष्कृत MAC ठेगाना बदल्ने सुविधा"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू देखाउनुहोस्"</string> @@ -285,8 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ब्याट्रीको खपत कम गरी नेटवर्कको कार्यसम्पादनमा सुधार गर्दछ"</string> - <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> - <skip /> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"यो टगलले क्लाइन्ट मोडमा मात्र MAC ठेगाना बदल्ने सुविधामा असर पार्न सक्छ।\nयो मोड सक्रिय हुँदा MAC बदल्ने सुविधा सक्षम पारेको कुनै पनि नेटवर्कको MAC ठेगाना पुनः बदल्न सकिन्छ। यसका लागि नेटवर्क कनेक्ट भएको हुनु पर्छ। यो कुरा क्लाइन्टले उक्त नेटवर्क पछिल्लो पटक कहिले डिस्कनेक्ट गरेको थियो भन्ने कुरामा पनि भर पर्छ। यन्त्र ४ घन्टा वा सोभन्दा कम समयमा फेरि कनेक्ट हुन्छ भने MAC ठेगाना पुनः बदलिँदैन।"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"सशुल्क वाइफाइ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"मिटर नगरिएको"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"लगर बफर आकारहरू"</string> @@ -438,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"लगभग <xliff:g id="TIME">%1$s</xliff:g> सम्म टिक्नु पर्छ"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> सम्म"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ब्याट्री <xliff:g id="TIME">%1$s</xliff:g> बजेसम्ममा सकिन सक्छ"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> भन्दा कम समय बाँकी छ"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> भन्दा कम समय बाँकी छ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> भन्दा बढी समय बाँकी छ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> भन्दा बढी समय बाँकी छ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"फोन चाँडै बन्द हुन सक्छ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ट्याब्लेट चाँडै बन्द हुन सक्छ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"यन्त्र चाँडै बन्द हुन सक्छ"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 176a8b7ca5cf..d034b496384d 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batterij is waarschijnlijk leeg om <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Nog minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Nog meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefoon wordt binnenkort mogelijk uitgeschakeld"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet wordt binnenkort mogelijk uitgeschakeld"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Apparaat wordt binnenkort mogelijk uitgeschakeld"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index e1610fb9406f..4341845bb75a 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -154,9 +154,9 @@ <string name="running_process_item_user_label" msgid="3988506293099805796">"ଉପଯୋଗକର୍ତ୍ତା: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <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_default_rate_title" msgid="3964187817364304022">"ସ୍ପୀଚ୍ ବେଗ"</string> + <string name="tts_settings" msgid="8130616705989351312">"ଟେକ୍ସଟ-ରୁ-ସ୍ପିଚ୍ ସେଟିଂସ୍"</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> <string name="tts_default_pitch_summary" msgid="9132719475281551884">"ସଂଶ୍ଳେଷିତ ସ୍ପିଚ୍ର ଟୋନ୍ରେ ପ୍ରଭାବ ପକାଏ"</string> @@ -421,7 +421,7 @@ <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ପ୍ରୋଟାନୋମାଲି (ଲାଲ୍-ସବୁଜ)"</string> <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ନୀଳ-ହଳଦିଆ)"</string> <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ରଙ୍ଗ ସଂଶୋଧନ"</string> - <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"ଆପଣଙ୍କ ଡିଭାଇସରେ ରଙ୍ଗଗୁଡ଼ିକ କିପରି ଡିସପ୍ଲେ ହୁଏ ତାହା ଆଡଜଷ୍ଟ କରିବାକୁ ’କଲର୍ କରେକ୍ସନ୍’ ଆପଣଙ୍କୁ ଅନୁମତି ଦିଏ"</string> + <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"ଆପଣଙ୍କ ଡିଭାଇସରେ ରଙ୍ଗଗୁଡ଼ିକ କିପରି ଡିସପ୍ଲେ ହୁଏ, ତାହା ଆଡଜଷ୍ଟ କରିବାକୁ \'ରଙ୍ଗ ସଂଶୋଧନ’ ଆପଣଙ୍କୁ ଅନୁମତି ଦିଏ"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ଦ୍ୱାରା ଓଭର୍ରାଇଡ୍ କରାଯାଇଛି"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ବଳକା ଅଛି"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"ବ୍ୟାଟେରୀ <xliff:g id="TIME">%1$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ ଚାଲିବ"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> ସୁଦ୍ଧା ବ୍ୟାଟେରୀର ଚାର୍ଜ ଶେଷ ହୋଇ ଯାଇପାରେ"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ରୁ କମ୍ ବ୍ୟାଟେରୀ ବାକି ଅଛି"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ରୁ କମ୍ ବ୍ୟାଟେରୀ ବାକି ଅଛି (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>ରୁ ଅଧିକ ବ୍ୟାଟେରୀ ବାକି ଅଛି (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>ରୁ ଅଧିକ ବ୍ୟାଟେରୀ ବାକି ଅଛି"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ଫୋନ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯାଇପାରେ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ଟାବଲେଟ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯାଇପାରେ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯାଇପାରେ"</string> @@ -536,16 +532,16 @@ <string name="user_add_profile_item_summary" msgid="5418602404308968028">"ନିଜ ଆକାଉଣ୍ଟରୁ ଆପ୍ ତଥା କଣ୍ଟେଣ୍ଟକୁ ଆପଣ ଆକ୍ସେସ୍ ରୋକିପାରିବେ"</string> <string name="user_add_user_item_title" msgid="2394272381086965029">"ଉପଯୋଗକର୍ତ୍ତା"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"ସୀମିତ ସୁବିଧା ଥିବା ପ୍ରୋଫାଇଲ୍"</string> - <string name="user_add_user_title" msgid="5457079143694924885">"ନୂତନ ୟୁଜର୍ ଯୋଡ଼ିବେ?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"ଅତିରିକ୍ତ ୟୁଜର୍ ତିଆରିକରି ଆପଣ ଏହି ଡିଭାଇସ୍କୁ ଅନ୍ୟ ଲୋକମାନଙ୍କ ସହିତ ସେୟାର୍ କରିପାରିବେ। ପ୍ରତ୍ୟେକ ୟୁଜର୍ଙ୍କର ନିଜର ସ୍ପେସ୍ ଅଛି ଯାହାକୁ ସେମାନେ ଆପ୍, ୱାଲପେପର୍ ଓ ଏପରି ଅନେକ ସହିତ କଷ୍ଟମାଇଜ୍ କରିପାରିବେ। ୟୁଜର୍ ୱାଇ-ଫାଇ ଭଳି ଡିଭାଇସ୍ ସେଟିଙ୍ଗକୁ ମଧ୍ୟ ଆଡଜଷ୍ଟ କରିପାରିବେ ଯାହା ସମସ୍ତଙ୍କୁ ପ୍ରଭାବିତ କରିଥାଏ। \n\nଯେତେବେଳେ ଆପଣ ଗୋଟିଏ ନୂଆ ୟୁଜର୍ଙ୍କୁ ଯୋଡ଼ିବେ ସେତେବେଳେ ସେହି ବ୍ୟକ୍ତି ଜଣଙ୍କୁ ନିଜର ସ୍ପେସ୍କୁ ସେଟଅପ୍ କରିବାକୁ ପଡ଼ିବ। \n\nଅନ୍ୟ ୟୁଜରଙ୍କ ପାଇଁ ଯେକୌଣସି ୟୁଜର୍ ଆପ୍କୁ ଅପଡେଟ୍ କରିପାରିବେ। ଆକ୍ସେସ୍ କରିବା ପାଇଁ ସେଟିଙ୍ଗ ଏବଂ ସେବା ନୂଆ ୟୁଜର୍ଙ୍କୁ ଟ୍ରନ୍ସଫର୍ ନହୋଇପାରେ।"</string> + <string name="user_add_user_title" msgid="5457079143694924885">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବେ?"</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"ଅତିରିକ୍ତ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରି ଆପଣ ଏହି ଡିଭାଇସ୍କୁ ଅନ୍ୟ ଲୋକମାନଙ୍କ ସହିତ ସେୟାର୍ କରିପାରିବେ। ପ୍ରତ୍ୟେକ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନିଜର ସ୍ପେସ୍ ଅଛି ଯାହାକୁ ସେମାନେ ଆପ୍, ୱାଲପେପର୍ ଓ ଏପରି ଅନେକ କିଛି ସହିତ କଷ୍ଟମାଇଜ୍ କରିପାରିବେ। ଉପଯୋଗକର୍ତ୍ତା ୱାଇ-ଫାଇ ଭଳି ଡିଭାଇସ୍ ସେଟିଂସକୁ ମଧ୍ୟ ଆଡଜଷ୍ଟ କରିପାରିବେ ଯାହା ସମସ୍ତଙ୍କୁ ପ୍ରଭାବିତ କରିଥାଏ। \n\nଯେତେବେଳେ ଆପଣ ଗୋଟିଏ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବେ, ସେତେବେଳେ ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ନିଜର ସ୍ପେସ୍କୁ ସେଟଅପ୍ କରିବାକୁ ପଡ଼ିବ। \n\nଅନ୍ୟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପ୍କୁ ଅପଡେଟ୍ କରିପାରିବେ। ଆକ୍ସେସିବିଲିଟୀ ସେଟିଂସ୍ ଏବଂ ସେବା ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ସ୍ଥାନାନ୍ତର ହୋଇନପାରେ।"</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଡ଼ିବାବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ସ୍ଥାନ ସେଟ୍ କରିବାକୁ ପଡ଼ିବ।\n\nଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେକୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପ୍ଗୁଡ଼ିକୁ ଅପ୍ଡେଟ୍ କରିପାରିବେ।"</string> - <string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ୟୁଜର୍ଙ୍କୁ ସେଟ୍ କରିବେ?"</string> - <string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ୍ ଓ ନିଜର ସ୍ଥାନ ସେଟ୍ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string> + <string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ଉପଯୋଗକର୍ତ୍ତା ସେଟଅପ କରିବେ?"</string> + <string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ୍ ଓ ନିଜର ସ୍ଥାନ ସେଟଅପ୍ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ପ୍ରୋଫାଇଲ୍କୁ ଏବେ ସେଟ୍ କରିବେ?"</string> - <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ଏବେ ସେଟ୍ କରନ୍ତୁ"</string> + <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ଏବେ ସେଟଅପ୍ କରନ୍ତୁ"</string> <string name="user_setup_button_setup_later" msgid="8712980133555493516">"ଏବେ ନୁହେଁଁ"</string> <string name="user_add_user_type_title" msgid="551279664052914497">"ଯୋଡନ୍ତୁ"</string> - <string name="user_new_user_name" msgid="60979820612818840">"ନୂଆ ୟୁଜର୍"</string> + <string name="user_new_user_name" msgid="60979820612818840">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"ନୂଆ ପ୍ରୋଫାଇଲ୍"</string> <string name="user_info_settings_title" msgid="6351390762733279907">"ଉପଯୋଗକର୍ତ୍ତା ସୂଚନା"</string> <string name="profile_info_settings_title" msgid="105699672534365099">"ପ୍ରୋଫାଇଲ୍ ସୂଚନା"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 4ba370b3a030..b47b5fb2e05e 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ ਚੱਲੇਗੀ"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ਬੈਟਰੀ <xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ ਖਤਮ ਹੋ ਸਕਦੀ ਹੈ"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਬਾਕੀ"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਤੋਂ ਵੱਧ ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਤੋਂ ਵੱਧ ਬਾਕੀ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ਫ਼ੋਨ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ਟੈਬਲੈੱਟ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ਡੀਵਾਈਸ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index d371c5254708..cc0543e01966 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Wybierz profil"</string> <string name="category_personal" msgid="6236798763159385225">"Osobiste"</string> - <string name="category_work" msgid="4014193632325996115">"Praca"</string> + <string name="category_work" msgid="4014193632325996115">"Służbowe"</string> <string name="development_settings_title" msgid="140296922921597393">"Opcje programistyczne"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Włącz opcje dla programistów"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Ustaw opcje związane z programowaniem aplikacji."</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Powinno wystarczyć do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria może się wyczerpać do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Wkrótce telefon może się wyłączyć"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet może się wkrótce wyłączyć"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Urządzenie może się wkrótce wyłączyć"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml index 4658ffdd859a..ca154e523f98 100644 --- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml +++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml @@ -61,7 +61,7 @@ <string-array name="bt_hci_snoop_log_entries"> <item msgid="695678520785580527">"Desativado"</item> <item msgid="6336372935919715515">"Filtro ativado"</item> - <item msgid="2779123106632690576">"Ativada"</item> + <item msgid="2779123106632690576">"Ativado"</item> </string-array> <string-array name="bluetooth_avrcp_versions"> <item msgid="8036025277512210160">"AVRCP 1.4 (padrão)"</item> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index e3adb389484c..6318c6d460b7 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desligado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"A desligar..."</string> @@ -508,7 +508,7 @@ <string name="alarm_template_far" msgid="6382760514842998629">"no(a) <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string> - <string name="zen_mode_forever" msgid="3339224497605461291">"Até ser desativado"</string> + <string name="zen_mode_forever" msgid="3339224497605461291">"Até desativar"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altifalante do telemóvel"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema ao ligar. Desligue e volte a ligar o dispositivo."</string> diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml index 4658ffdd859a..ca154e523f98 100644 --- a/packages/SettingsLib/res/values-pt/arrays.xml +++ b/packages/SettingsLib/res/values-pt/arrays.xml @@ -61,7 +61,7 @@ <string-array name="bt_hci_snoop_log_entries"> <item msgid="695678520785580527">"Desativado"</item> <item msgid="6336372935919715515">"Filtro ativado"</item> - <item msgid="2779123106632690576">"Ativada"</item> + <item msgid="2779123106632690576">"Ativado"</item> </string-array> <string-array name="bluetooth_avrcp_versions"> <item msgid="8036025277512210160">"AVRCP 1.4 (padrão)"</item> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index fa43c13c7ccb..f64cfbfe07b5 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ar trebui să reziste până la <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Până la <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria se poate descărca până la <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"A mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"A mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"A mai rămas mai mult de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"A mai rămas mai mult de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonul se poate închide în curând"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tableta se poate închide în curând"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Dispozitivul se poate închide în curând"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index bb060711cf17..71c7cf352f7c 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Заряда хватит примерно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея может разрядиться к <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Осталось менее <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит менее чем на <xliff:g id="THRESHOLD">%1$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит более чем на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Осталось более <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон скоро выключится"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет скоро выключится"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Устройство скоро выключится"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index ea8cf7313d91..f988d468fede 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -435,15 +435,11 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batéria sa môže do <xliff:g id="TIME">%1$s</xliff:g> minúť"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batéria sa môže do <xliff:g id="TIME">%1$s</xliff:g> vybiť"</string> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Zostáva viac ako <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Zostáva viac ako <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefón sa môže čoskoro vypnúť"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet sa môže čoskoro vypnúť"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Zariadenie sa môže čoskoro vypnúť"</string> diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml index eb860743b796..80042a60fb81 100644 --- a/packages/SettingsLib/res/values-sl/arrays.xml +++ b/packages/SettingsLib/res/values-sl/arrays.xml @@ -40,7 +40,7 @@ <item msgid="8339720953594087771">"Vzpostavljanje povezave z omrežjem <xliff:g id="NETWORK_NAME">%1$s</xliff:g> …"</item> <item msgid="3028983857109369308">"Preverjanje pristnosti v omrežju <xliff:g id="NETWORK_NAME">%1$s</xliff:g> …"</item> <item msgid="4287401332778341890">"Pridobivanje naslova IP od <xliff:g id="NETWORK_NAME">%1$s</xliff:g> …"</item> - <item msgid="1043944043827424501">"Povezava z omrežjem <xliff:g id="NETWORK_NAME">%1$s</xliff:g> je vzpostavljena"</item> + <item msgid="1043944043827424501">"Povezava z: <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> <item msgid="7445993821842009653">"Začasno ustavljeno"</item> <item msgid="1175040558087735707">"Prekinjanje povezave z omrežjem <xliff:g id="NETWORK_NAME">%1$s</xliff:g> …"</item> <item msgid="699832486578171722">"Prekinjena povezava"</item> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 893b20739717..eb2077cfbf44 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Moralo bi zadostovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Energije baterije lahko zmanjka do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Preostaja manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Preostaja manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Preostaja več kot <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Preostaja več kot <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon se bo morda kmalu zaustavil"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablični računalnik se bo morda kmalu zaustavil"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Naprava se bo morda kmalu zaustavila"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 72b28ce5ece6..685be99fdab0 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -454,7 +454,7 @@ <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Po ngarkon me shpejtësi"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Po karikohet ngadalë"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nuk po karikohet"</string> - <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Në prizë, por nuk mund të ngarkohet për momentin"</string> + <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Në prizë, por nuk mund të karikohet për momentin"</string> <string name="battery_info_status_full" msgid="4443168946046847468">"E mbushur"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolluar nga administratori"</string> <string name="disabled" msgid="8017887509554714950">"Çaktivizuar"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index e47969cef612..9188a76248ac 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерија ће се можда испразнити до <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон ће се ускоро искључити"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет ће се ускоро искључити"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Уређај ће се ускоро искључити"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index c21e62490f0a..c383e57739bb 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Bör räcka ungefär till klockan <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Till kl. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet kan ta slut klockan <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mer än <xliff:g id="TIME_REMAINING">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Mer än <xliff:g id="TIME_REMAINING">%1$s</xliff:g> återstår"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen kanske stängs av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Surfplattan kanske stängs av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheten kanske stängs av snart"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 4494d1a7ec68..a57fd0e87e1f 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"<xliff:g id="TIME">%1$s</xliff:g> வரை பயன்படுத்த முடியும்"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> வரை"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g>க்கு பேட்டரி காலியாகிவிடக்கூடும்"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ஐ விடக் குறைவாக உள்ளது"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ஐ விடக் குறைவாக உள்ளது (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>க்கு மேல் உள்ளது (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>க்கு மேல் உள்ளது"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"மொபைல் விரைவில் ஆஃப் ஆகக்கூடும்"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"டேப்லெட் விரைவில் ஆஃப் ஆகக்கூடும்"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"சாதனம் விரைவில் ஆஃப் ஆகக்கூடும்"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index ff958ea1159a..b6186106cfa0 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"దాదాపు <xliff:g id="TIME">%1$s</xliff:g> వరకు ఉండాలి"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> వరకు"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"బ్యాటరీ <xliff:g id="TIME">%1$s</xliff:g> సమయానికి ఖాళీ అవ్వచ్చు"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> కంటే తక్కువ సమయం మిగిలి ఉంది"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> కంటే తక్కువ సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> కంటే ఎక్కువ సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> కంటే ఎక్కువ సమయం మిగిలి ఉంది"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ఫోన్ త్వరలో షట్డౌన్ కావచ్చు"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"టాబ్లెట్ త్వరలో షట్డౌన్ కావచ్చు"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"పరికరం త్వరలో షట్డౌన్ కావచ్చు"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 844a329b8df5..315fab9c0052 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"น่าจะใช้งานได้ถึงเวลาประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"จนถึง <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"แบตเตอรี่อาจหมดภายใน <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"เหลือน้อยกว่า <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"เหลือน้อยกว่า <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"เหลืออีกกว่า <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"เหลืออีกกว่า <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"โทรศัพท์อาจปิดเครื่องในไม่ช้า"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"แท็บเล็ตอาจปิดเครื่องในไม่ช้า"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"อุปกรณ์อาจปิดเครื่องในไม่ช้า"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 412be0f2b3aa..2ea03a4eaa71 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hanggang <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Posibleng maubos ang baterya sa loob ng <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Baka mag-shut down na ang telepono"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Baka mag-shut down na ang tablet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Baka mag-shut down na ang device"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 6f6b3fc84cf1..a6021d233555 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Вистачить приблизно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Акумулятор може розрядитися до <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Залишилося понад <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Залишилося понад <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон може невдовзі вимкнутися"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет може невдовзі вимкнутися"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Пристрій може невдовзі вимкнутися"</string> @@ -458,7 +454,7 @@ <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Швидке заряджання"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Повільне заряджання"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не заряджається"</string> - <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Підключено. Не вдається зарядити"</string> + <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Підключено, не заряджається"</string> <string name="battery_info_status_full" msgid="4443168946046847468">"Акумулятор заряджено"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Керується адміністратором"</string> <string name="disabled" msgid="8017887509554714950">"Вимкнено"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 32515ace5b4a..a425805963f0 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> تک بیٹری چلے گی"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> تک"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> تک بیٹری ختم ہو سکتی ہے"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> سے زیادہ باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> سے زیادہ باقی ہے"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"فون جلد ہی بند ہو سکتا ہے"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ٹیبلیٹ جلد ہی بند ہو سکتا ہے"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"آلہ جلد ہی بند ہو سکتا ہے"</string> diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml index 892ebe0a6e9e..26153adfef2a 100644 --- a/packages/SettingsLib/res/values-uz/arrays.xml +++ b/packages/SettingsLib/res/values-uz/arrays.xml @@ -40,7 +40,7 @@ <item msgid="8339720953594087771">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> tarmog‘iga ulanilmoqda…"</item> <item msgid="3028983857109369308">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> bilan aloqa o‘rnatilyapti…"</item> <item msgid="4287401332778341890">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> IP manzil beryapti…"</item> - <item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> tarmog‘iga ulanildi"</item> + <item msgid="1043944043827424501">"Bunga ulangan: <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> <item msgid="7445993821842009653">"Muzlatildi"</item> <item msgid="1175040558087735707">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> tarmog‘idan uzilmoqda…"</item> <item msgid="699832486578171722">"Uzildi"</item> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 215cb4c83d58..3089b7091eea 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -76,7 +76,7 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (telefondan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (mediadan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (telefon yoki mediadan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Faol, batariya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Faol, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Faol, L: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> <string name="bluetooth_battery_level" msgid="2893696778200201555">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> @@ -129,8 +129,8 @@ <string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth"</string> <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"Chap eshitish apparati ulanmoqda…"</string> <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"O‘ng eshitish apparati ulanmoqda…"</string> - <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Chap eshitish apparati – batariya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"O‘ng eshitish apparati – batariya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Chap eshitish apparati, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"O‘ng eshitish apparati, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="accessibility_wifi_off" msgid="1195445715254137155">"Wi-Fi o‘chiq."</string> <string name="accessibility_no_wifi" msgid="5297119459491085771">"Wi-Fi o‘chiq."</string> <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"Wi-Fi: bitta ustun"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha davom etadi"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> gacha"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batareya quvvati tugash vaqti: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kam qoldi"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kam qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>dan koʻproq qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>dan koʻproq qoldi"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon tez orada oʻchib qolishi mumkin"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planshet tez orada oʻchib qolishi mumkin"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Qurilma tez orada oʻchib qolishi mumkin"</string> @@ -451,8 +447,8 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Planshet tez orada oʻchib qolishi mumkin (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Qurilma tez orada oʻchib qolishi mumkin (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ichida toʻliq quvvat oladi"</string> - <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida toʻliq quvvat oladi"</string> + <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ichida toʻladi"</string> + <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida toʻladi"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Noma’lum"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Quvvat olmoqda"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Tezkor quvvat olmoqda"</string> diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml index db29bc86e8a8..3a7e55afb124 100644 --- a/packages/SettingsLib/res/values-vi/arrays.xml +++ b/packages/SettingsLib/res/values-vi/arrays.xml @@ -152,7 +152,7 @@ <string-array name="bluetooth_audio_active_device_summaries"> <item msgid="8019740759207729126"></item> <item msgid="204248102837117183">", đang hoạt động"</item> - <item msgid="253388653486517049">", đang hoạt động (nội dung phương tiện)"</item> + <item msgid="253388653486517049">", đang hoạt động (nội dung nghe nhìn)"</item> <item msgid="5001852592115448348">", đang hoạt động (điện thoại)"</item> </string-array> <string-array name="select_logd_size_titles"> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index e118ec0b72f1..32fbcc90963f 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Pin sẽ hết vào khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Cho đến <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Điện thoại có thể hết pin vào <xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Còn chưa đến <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Còn chưa đến <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Còn hơn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Còn hơn <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Điện thoại có thể sắp tắt"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Máy tính bảng có thể sắp tắt"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Thiết bị có thể sắp tắt"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 9edcff2c6e5e..7270c2e2971d 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"直到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"电池电量可能在<xliff:g id="TIME">%1$s</xliff:g> 前耗尽"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"剩余电池续航时间超过 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"剩余电池续航时间超过 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"手机可能即将关机"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"平板电脑可能即将关机"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"设备可能即将关机"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 974831f19cfe..5d73f3e5ee13 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -435,7 +435,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"電量大約可用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"還可用到<xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電量可能將於<xliff:g id="TIME">%1$s</xliff:g>耗盡"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電量可能將於<xliff:g id="TIME">%1$s</xliff:g> 耗盡"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"剩餘電量少於 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"剩餘電量少於 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"剩餘電量時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 04b5cb6ba2c9..6fefa31b0fb7 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -253,7 +253,7 @@ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi-Fi 掃描調節"</string> <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi 加強型 MAC 隨機化"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"行動數據連線一律保持啟用狀態"</string> - <string name="tethering_hardware_offload" msgid="4116053719006939161">"數據連線硬體加速"</string> + <string name="tethering_hardware_offload" msgid="4116053719006939161">"網路共用硬體加速"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"顯示沒有名稱的藍牙裝置"</string> <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"停用絕對音量功能"</string> <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"啟用 Gabeldorsche"</string> @@ -299,7 +299,7 @@ <string name="allow_mock_location_summary" msgid="179780881081354579">"允許模擬位置"</string> <string name="debug_view_attributes" msgid="3539609843984208216">"啟用檢視屬性檢查"</string> <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"即使 Wi‑Fi 連線已啟用,一律將行動數據連線保持啟用狀態 (以便快速切換網路)。"</string> - <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"使用數據連線硬體加速功能 (如果可用的話)"</string> + <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"使用網路共用硬體加速功能 (如果可用的話)"</string> <string name="adb_warning_title" msgid="7708653449506485728">"允許 USB 偵錯嗎?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB 偵錯是針對應用程式開發而設計的功能,可讓你複製電腦和裝置中的資料、不需經由通知即可在裝置上安裝應用程式,以及讀取記錄資料。"</string> <string name="adbwifi_warning_title" msgid="727104571653031865">"要啟用無線偵錯嗎?"</string> @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"預估電力大約可使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電力可能於<xliff:g id="TIME">%1$s</xliff:g> 前耗盡"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"電池可用時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"電池可用時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"手機可能即將關機"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"平板電腦可能即將關機"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"裝置可能即將關機"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 7e849189f62e..6cb24e6e55d2 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -436,14 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Kumele ihlale cishe kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Kuze kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Ibhethri lingaphela ngo-<xliff:g id="TIME">%1$s</xliff:g>"</string> - <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> - <skip /> - <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> - <skip /> - <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> - <skip /> - <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> - <skip /> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kusele okungaphansi kuka-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kusele okungaphansi kuka-<xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Kusele okungaphezu kuka-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Kusele okungaphezu kuka-<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Ifoni ingacisha maduze"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Ithebulethi ingacisha maduze"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Idivayisi ingacisha maduze"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 7baaf494771b..7587cc1338f4 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -937,11 +937,6 @@ <!-- UI debug setting: show missing channel toasts summary [CHAR LIMIT=50] --> <string name="show_notification_channel_warnings_summary">Displays on-screen warning when an app posts a notification without a valid channel</string> - <!-- UI debug setting: enforce shortcut requirements for conversation space [CHAR LIMIT=25] --> - <string name="enforce_shortcuts_for_conversations">Enforce shortcuts for conversation notifications</string> - <!-- UI debug setting: enforce shortcut requirements for conversation space summary [CHAR LIMIT=50] --> - <string name="enforce_shortcuts_for_conversations_summary">Require notifications to be backed by a long-lived sharing shortcut in order to appear in the conversation section</string> - <!-- UI debug setting: force allow apps on external storage [CHAR LIMIT=50] --> <string name="force_allow_on_external">Force allow apps on external</string> <!-- UI debug setting: force allow on external summary [CHAR LIMIT=150] --> diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index f4857932064f..eb02a1c8b880 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -279,8 +279,12 @@ public class Utils { } public static int getThemeAttr(Context context, int attr) { + return getThemeAttr(context, attr, 0); + } + + public static int getThemeAttr(Context context, int attr, int defaultValue) { TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); - int theme = ta.getResourceId(0, 0); + int theme = ta.getResourceId(0, defaultValue); ta.recycle(); return theme; } diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java index 7ef080178a2f..bd0b9e93b09d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java +++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java @@ -185,7 +185,12 @@ public class MetricsFeatureProvider { sourceMetricsCategory); } - private boolean logSettingsTileClick(String logKey, int sourceMetricsCategory) { + /** + * Logs an event when the setting key is clicked. + * + * @return true if the key is loggable, otherwise false + */ + public boolean logSettingsTileClick(String logKey, int sourceMetricsCategory) { if (TextUtils.isEmpty(logKey)) { // Not loggable return false; diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java index 57e680849fec..ab7b54d98285 100644 --- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java +++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java @@ -159,6 +159,25 @@ public class DreamBackend { return null; } + /** + * Gets an icon from active dream. + */ + public Drawable getActiveIcon() { + final ComponentName cn = getActiveDream(); + if (cn != null) { + final PackageManager pm = mContext.getPackageManager(); + try { + final ServiceInfo ri = pm.getServiceInfo(cn, 0); + if (ri != null) { + return ri.loadIcon(pm); + } + } catch (PackageManager.NameNotFoundException exc) { + return null; + } + } + return null; + } + public @WhenToDream int getWhenToDreamSetting() { if (!isEnabled()) { return NEVER; diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java index ee8fb38ef08c..74a59399feee 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java @@ -89,6 +89,13 @@ public class BluetoothMediaDevice extends MediaDevice { } @Override + public boolean isFastPairDevice() { + return mCachedDevice != null + && BluetoothUtils.getBooleanMetaData( + mCachedDevice.getDevice(), BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET); + } + + @Override public boolean isConnected() { return mCachedDevice.getBondState() == BluetoothDevice.BOND_BONDED && mCachedDevice.isConnected(); diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java index 19c8b20b7822..002bbec60924 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java @@ -17,11 +17,16 @@ package com.android.settingslib.media; import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_DOCK; import static android.media.MediaRoute2Info.TYPE_GROUP; +import static android.media.MediaRoute2Info.TYPE_HDMI; import static android.media.MediaRoute2Info.TYPE_HEARING_AID; import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; import static android.media.MediaRoute2Info.TYPE_REMOTE_TV; import static android.media.MediaRoute2Info.TYPE_UNKNOWN; +import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY; +import static android.media.MediaRoute2Info.TYPE_USB_DEVICE; +import static android.media.MediaRoute2Info.TYPE_USB_HEADSET; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR; @@ -339,7 +344,7 @@ public class InfoMediaManager extends MediaManager { for (MediaRoute2Info route : mRouterManager.getAllRoutes()) { if (DEBUG) { Log.d(TAG, "buildAllRoutes() route : " + route.getName() + ", volume : " - + route.getVolume()); + + route.getVolume() + ", type : " + route.getType()); } if (route.isSystemRoute()) { addMediaDevice(route); @@ -350,13 +355,15 @@ public class InfoMediaManager extends MediaManager { private void buildAvailableRoutes() { for (MediaRoute2Info route : mRouterManager.getAvailableRoutes(mPackageName)) { if (DEBUG) { - Log.d(TAG, "buildAvailableRoutes() route : " + route.getName()); + Log.d(TAG, "buildAvailableRoutes() route : " + route.getName() + + ", type : " + route.getType()); } addMediaDevice(route); } } - private void addMediaDevice(MediaRoute2Info route) { + @VisibleForTesting + void addMediaDevice(MediaRoute2Info route) { final int deviceType = route.getType(); MediaDevice mediaDevice = null; switch (deviceType) { @@ -374,6 +381,11 @@ public class InfoMediaManager extends MediaManager { } break; case TYPE_BUILTIN_SPEAKER: + case TYPE_USB_DEVICE: + case TYPE_USB_HEADSET: + case TYPE_USB_ACCESSORY: + case TYPE_DOCK: + case TYPE_HDMI: case TYPE_WIRED_HEADSET: case TYPE_WIRED_HEADPHONES: mediaDevice = @@ -385,8 +397,10 @@ public class InfoMediaManager extends MediaManager { BluetoothAdapter.getDefaultAdapter().getRemoteDevice(route.getOriginalId()); final CachedBluetoothDevice cachedDevice = mBluetoothManager.getCachedDeviceManager().findDevice(device); - mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice, mRouterManager, - route, mPackageName); + if (cachedDevice != null) { + mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice, mRouterManager, + route, mPackageName); + } break; default: Log.w(TAG, "addMediaDevice() unknown device type : " + deviceType); diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index a62d76f732da..af691783e85d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -35,6 +35,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -185,7 +186,7 @@ public class LocalMediaManager implements BluetoothCallback { } void dispatchDeviceListUpdate() { - //TODO(b/149260820): Use new rule to rank device once device type api is ready. + Collections.sort(mMediaDevices, COMPARATOR); for (DeviceCallback callback : getCallbacks()) { callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices)); } diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java index 6aff301f57d4..f1c0f6b44150 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java @@ -17,11 +17,16 @@ package com.android.settingslib.media; import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_DOCK; import static android.media.MediaRoute2Info.TYPE_GROUP; +import static android.media.MediaRoute2Info.TYPE_HDMI; import static android.media.MediaRoute2Info.TYPE_HEARING_AID; import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; import static android.media.MediaRoute2Info.TYPE_REMOTE_TV; import static android.media.MediaRoute2Info.TYPE_UNKNOWN; +import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY; +import static android.media.MediaRoute2Info.TYPE_USB_DEVICE; +import static android.media.MediaRoute2Info.TYPE_USB_HEADSET; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; @@ -102,6 +107,13 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { case TYPE_WIRED_HEADPHONES: mType = MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE; break; + case TYPE_USB_DEVICE: + case TYPE_USB_HEADSET: + case TYPE_USB_ACCESSORY: + case TYPE_DOCK: + case TYPE_HDMI: + mType = MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE; + break; case TYPE_HEARING_AID: case TYPE_BLUETOOTH_A2DP: mType = MediaDeviceType.TYPE_BLUETOOTH_DEVICE; @@ -266,16 +278,22 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { /** * Rules: - * 1. If there is one of the connected devices identified as a carkit, this carkit will - * be always on the top of the device list. Rule 2 and Rule 3 can’t overrule this rule. + * 1. If there is one of the connected devices identified as a carkit or fast pair device, + * the fast pair device will be always on the first of the device list and carkit will be + * second. Rule 2 and Rule 3 can’t overrule this rule. * 2. For devices without any usage data yet * WiFi device group sorted by alphabetical order + BT device group sorted by alphabetical * order + phone speaker * 3. For devices with usage record. * The most recent used one + device group with usage info sorted by how many times the * device has been used. - * 4. Phone device always in the top and the connected Bluetooth devices, cast devices and - * phone device will be always above on the disconnect Bluetooth devices. + * 4. The order is followed below rule: + * 1. USB-C audio device + * 2. 3.5 mm audio device + * 3. Bluetooth device + * 4. Cast device + * 5. Cast group device + * 6. Phone * * So the device list will look like 5 slots ranked as below. * Rule 4 + Rule 1 + the most recently used device + Rule 3 + Rule 2 @@ -295,39 +313,50 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { } } - // Phone device always in the top. - if (mType == MediaDeviceType.TYPE_PHONE_DEVICE) { - return -1; - } else if (another.mType == MediaDeviceType.TYPE_PHONE_DEVICE) { - return 1; - } - // Check carkit - if (isCarKitDevice()) { - return -1; - } else if (another.isCarKitDevice()) { - return 1; - } - // Set last used device at the first item - String lastSelectedDevice = ConnectionRecordManager.getInstance().getLastSelectedDevice(); - if (TextUtils.equals(lastSelectedDevice, getId())) { - return -1; - } else if (TextUtils.equals(lastSelectedDevice, another.getId())) { - return 1; - } - // Sort by how many times the device has been used if there is usage record - if ((mConnectedRecord != another.mConnectedRecord) - && (another.mConnectedRecord > 0 || mConnectedRecord > 0)) { - return (another.mConnectedRecord - mConnectedRecord); - } - // Both devices have never been used - // To devices with the same type, sort by alphabetical order if (mType == another.mType) { + // Check fast pair device + if (isFastPairDevice()) { + return -1; + } else if (another.isFastPairDevice()) { + return 1; + } + + // Check carkit + if (isCarKitDevice()) { + return -1; + } else if (another.isCarKitDevice()) { + return 1; + } + + // Set last used device at the first item + final String lastSelectedDevice = ConnectionRecordManager.getInstance() + .getLastSelectedDevice(); + if (TextUtils.equals(lastSelectedDevice, getId())) { + return -1; + } else if (TextUtils.equals(lastSelectedDevice, another.getId())) { + return 1; + } + // Sort by how many times the device has been used if there is usage record + if ((mConnectedRecord != another.mConnectedRecord) + && (another.mConnectedRecord > 0 || mConnectedRecord > 0)) { + return (another.mConnectedRecord - mConnectedRecord); + } + + // Both devices have never been used + // To devices with the same type, sort by alphabetical order final String s1 = getName(); final String s2 = another.getName(); return s1.compareToIgnoreCase(s2); + } else { + // Both devices have never been used, the priority is: + // 1. USB-C audio device + // 2. 3.5 mm audio device + // 3. Bluetooth device + // 4. Cast device + // 5. Cast group device + // 6. Phone + return mType < another.mType ? -1 : 1; } - // Both devices have never been used, the priority is Phone > Cast > Bluetooth - return mType - another.mType; } /** @@ -338,6 +367,14 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { return false; } + /** + * Check if it is FastPair device + * @return {@code true} if it is FastPair device, otherwise return {@code false} + */ + protected boolean isFastPairDevice() { + return false; + } + @Override public boolean equals(Object obj) { if (!(obj instanceof MediaDevice)) { diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java index c6c5ade90eb5..42f2542e5c30 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java @@ -16,6 +16,11 @@ package com.android.settingslib.media; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_DOCK; +import static android.media.MediaRoute2Info.TYPE_HDMI; +import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY; +import static android.media.MediaRoute2Info.TYPE_USB_DEVICE; +import static android.media.MediaRoute2Info.TYPE_USB_HEADSET; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; @@ -53,6 +58,13 @@ public class PhoneMediaDevice extends MediaDevice { switch (mRouteInfo.getType()) { case TYPE_WIRED_HEADSET: case TYPE_WIRED_HEADPHONES: + name = mContext.getString(R.string.media_transfer_wired_device_name); + break; + case TYPE_USB_DEVICE: + case TYPE_USB_HEADSET: + case TYPE_USB_ACCESSORY: + case TYPE_DOCK: + case TYPE_HDMI: name = mRouteInfo.getName(); break; case TYPE_BUILTIN_SPEAKER: @@ -78,6 +90,11 @@ public class PhoneMediaDevice extends MediaDevice { int getDrawableResId() { int resId; switch (mRouteInfo.getType()) { + case TYPE_USB_DEVICE: + case TYPE_USB_HEADSET: + case TYPE_USB_ACCESSORY: + case TYPE_DOCK: + case TYPE_HDMI: case TYPE_WIRED_HEADSET: case TYPE_WIRED_HEADPHONES: resId = com.android.internal.R.drawable.ic_bt_headphones_a2dp; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java index 204a93333d81..0e2a3cbbbd75 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java @@ -218,4 +218,29 @@ public class MetricsFeatureProviderTest { assertThat(mProvider.getAttribution(activity)).isEqualTo(100); } + + @Test + public void logSettingsTileClick_hasKey_shouldLog() { + final String key = "abc"; + final boolean loggable = mProvider.logSettingsTileClick(key, + MetricsEvent.SETTINGS_GESTURES); + + assertThat(loggable).isTrue(); + verify(mLogWriter).action( + MetricsEvent.SETTINGS_GESTURES, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + key, + 0); + } + + @Test + public void logSettingsTileClick_keyEmpty_shouldNotLog() { + final String key = ""; + boolean loggable = mProvider.logSettingsTileClick(key, + MetricsEvent.SETTINGS_GESTURES); + + assertThat(loggable).isFalse(); + verifyNoMoreInteractions(mLogWriter); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java index a39bcb7f08f6..8973d116e438 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java @@ -18,6 +18,7 @@ package com.android.settingslib.media; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothDevice; @@ -69,4 +70,30 @@ public class BluetoothMediaDeviceTest { assertThat(mBluetoothMediaDevice.isConnected()).isFalse(); } + + @Test + public void isFastPairDevice_isUntetheredHeadset_returnTrue() { + final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class); + when(mDevice.getDevice()).thenReturn(bluetoothDevice); + + final String value = "True"; + final byte[] bytes = value.getBytes(); + when(bluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) + .thenReturn(bytes); + + assertThat(mBluetoothMediaDevice.isFastPairDevice()).isTrue(); + } + + @Test + public void isFastPairDevice_isNotUntetheredHeadset_returnFalse() { + final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class); + when(mDevice.getDevice()).thenReturn(bluetoothDevice); + + final String value = "asjdaioshfaio"; + final byte[] bytes = value.getBytes(); + when(bluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) + .thenReturn(bytes); + + assertThat(mBluetoothMediaDevice.isFastPairDevice()).isFalse(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java index c21582cdf203..76eea67f9765 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java @@ -16,20 +16,29 @@ package com.android.settingslib.media; +import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP; +import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_USB_DEVICE; +import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; import static android.media.MediaRoute2ProviderService.REASON_NETWORK_ERROR; import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothDevice; import android.content.Context; import android.media.MediaRoute2Info; import android.media.MediaRouter2Manager; import android.media.RoutingSessionInfo; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.testutils.shadow.ShadowRouter2Manager; @@ -601,4 +610,60 @@ public class InfoMediaManagerTest { assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size()); verify(mCallback).onConnectedDeviceChanged(null); } + + @Test + public void addMediaDevice_verifyDeviceTypeCanCorrespondToMediaDevice() { + final MediaRoute2Info route2Info = mock(MediaRoute2Info.class); + final CachedBluetoothDeviceManager cachedBluetoothDeviceManager = + mock(CachedBluetoothDeviceManager.class); + final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); + + when(route2Info.getType()).thenReturn(TYPE_REMOTE_SPEAKER); + mInfoMediaManager.addMediaDevice(route2Info); + assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof InfoMediaDevice).isTrue(); + + when(route2Info.getType()).thenReturn(TYPE_USB_DEVICE); + mInfoMediaManager.mMediaDevices.clear(); + mInfoMediaManager.addMediaDevice(route2Info); + assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue(); + + when(route2Info.getType()).thenReturn(TYPE_WIRED_HEADSET); + mInfoMediaManager.mMediaDevices.clear(); + mInfoMediaManager.addMediaDevice(route2Info); + assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue(); + + when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP); + when(route2Info.getOriginalId()).thenReturn("00:00:00:00:00:00"); + when(mLocalBluetoothManager.getCachedDeviceManager()) + .thenReturn(cachedBluetoothDeviceManager); + when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class))) + .thenReturn(cachedDevice); + mInfoMediaManager.mMediaDevices.clear(); + mInfoMediaManager.addMediaDevice(route2Info); + assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof BluetoothMediaDevice).isTrue(); + + when(route2Info.getType()).thenReturn(TYPE_BUILTIN_SPEAKER); + mInfoMediaManager.mMediaDevices.clear(); + mInfoMediaManager.addMediaDevice(route2Info); + assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue(); + } + + @Test + public void addMediaDevice_cachedBluetoothDeviceIsNull_shouldNotAdded() { + final MediaRoute2Info route2Info = mock(MediaRoute2Info.class); + final CachedBluetoothDeviceManager cachedBluetoothDeviceManager = + mock(CachedBluetoothDeviceManager.class); + + when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP); + when(route2Info.getOriginalId()).thenReturn("00:00:00:00:00:00"); + when(mLocalBluetoothManager.getCachedDeviceManager()) + .thenReturn(cachedBluetoothDeviceManager); + when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class))) + .thenReturn(null); + + mInfoMediaManager.mMediaDevices.clear(); + mInfoMediaManager.addMediaDevice(route2Info); + + assertThat(mInfoMediaManager.mMediaDevices.size()).isEqualTo(0); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java index 206c8590a952..f3b49a69201b 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java @@ -16,6 +16,7 @@ package com.android.settingslib.media; +import static android.bluetooth.BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES; import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR; import static com.google.common.truth.Truth.assertThat; @@ -28,6 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.media.MediaRoute2Info; @@ -659,6 +661,7 @@ public class LocalMediaManagerTest { final BluetoothDevice bluetoothDevice4 = mock(BluetoothDevice.class); final BluetoothDevice bluetoothDevice5 = mock(BluetoothDevice.class); final BluetoothDevice bluetoothDevice6 = mock(BluetoothDevice.class); + final BluetoothClass bluetoothClass = mock(BluetoothClass.class); final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); final CachedBluetoothDeviceManager cachedManager = mock(CachedBluetoothDeviceManager.class); bluetoothDevices.add(bluetoothDevice); @@ -678,6 +681,9 @@ public class LocalMediaManagerTest { when(cachedManager.findDevice(bluetoothDevice6)).thenReturn(cachedDevice); when(cachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(cachedDevice.isConnected()).thenReturn(false); + when(cachedDevice.getDevice()).thenReturn(bluetoothDevice); + when(bluetoothDevice.getBluetoothClass()).thenReturn(bluetoothClass); + when(bluetoothClass.getDeviceClass()).thenReturn(AUDIO_VIDEO_HEADPHONES); when(device1.getId()).thenReturn(TEST_DEVICE_ID_1); when(device2.getId()).thenReturn(TEST_DEVICE_ID_2); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java index db05b768f5db..6664870a6257 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java @@ -18,9 +18,11 @@ package com.android.settingslib.media; import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -210,14 +212,14 @@ public class MediaDeviceTest { } @Test - public void compareTo_carKit_phone_phoneFirst() { + public void compareTo_carKit_phone_carKitFirst() { when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass); - mMediaDevices.add(mBluetoothMediaDevice1); mMediaDevices.add(mPhoneMediaDevice); + mMediaDevices.add(mBluetoothMediaDevice1); - assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); - Collections.sort(mMediaDevices, COMPARATOR); assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); } @Test @@ -281,7 +283,7 @@ public class MediaDeviceTest { } @Test - public void compareTo_info_bluetooth_infoFirst() { + public void compareTo_info_bluetooth_bluetoothFirst() { mMediaDevices.add(mInfoMediaDevice1); mMediaDevices.add(mBluetoothMediaDevice1); @@ -291,13 +293,45 @@ public class MediaDeviceTest { } @Test - public void compareTo_bluetooth_phone_phoneFirst() { - mMediaDevices.add(mBluetoothMediaDevice1); + public void compareTo_bluetooth_phone_bluetoothFirst() { mMediaDevices.add(mPhoneMediaDevice); + mMediaDevices.add(mBluetoothMediaDevice1); + + assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + } + + @Test + public void compareTo_bluetooth_wiredHeadset_wiredHeadsetFirst() { + final MediaRoute2Info phoneRouteInfo = mock(MediaRoute2Info.class); + when(phoneRouteInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES); + + final PhoneMediaDevice phoneMediaDevice = new PhoneMediaDevice(mContext, + mMediaRouter2Manager, phoneRouteInfo, TEST_PACKAGE_NAME); + + mMediaDevices.add(mBluetoothMediaDevice1); + mMediaDevices.add(phoneMediaDevice); assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); Collections.sort(mMediaDevices, COMPARATOR); - assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice); + assertThat(mMediaDevices.get(0)).isEqualTo(phoneMediaDevice); + } + + @Test + public void compareTo_info_wiredHeadset_wiredHeadsetFirst() { + final MediaRoute2Info phoneRouteInfo = mock(MediaRoute2Info.class); + when(phoneRouteInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES); + + final PhoneMediaDevice phoneMediaDevice = new PhoneMediaDevice(mContext, + mMediaRouter2Manager, phoneRouteInfo, TEST_PACKAGE_NAME); + + mMediaDevices.add(mInfoMediaDevice1); + mMediaDevices.add(phoneMediaDevice); + + assertThat(mMediaDevices.get(0)).isEqualTo(mInfoMediaDevice1); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(phoneMediaDevice); } @Test @@ -338,7 +372,7 @@ public class MediaDeviceTest { // 5.mBluetoothMediaDevice2: * 2 times usage // 6.mBluetoothMediaDevice3: * 1 time usage // 7.mPhoneMediaDevice: * 0 time usage - // Order: 7 -> 2 -> 1 -> 5 -> 3 -> 6 -> 4 + // Order: 2 -> 5 -> 6 -> 1 -> 3 -> 4 -> 7 @Test public void compareTo_mixedDevices_carKitFirst() { when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass); @@ -360,13 +394,13 @@ public class MediaDeviceTest { mInfoMediaDevice1.connect(); Collections.sort(mMediaDevices, COMPARATOR); - assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice); - assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice1); - assertThat(mMediaDevices.get(2)).isEqualTo(mInfoMediaDevice1); - assertThat(mMediaDevices.get(3)).isEqualTo(mBluetoothMediaDevice2); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice2); + assertThat(mMediaDevices.get(2)).isEqualTo(mBluetoothMediaDevice3); + assertThat(mMediaDevices.get(3)).isEqualTo(mInfoMediaDevice1); assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice2); - assertThat(mMediaDevices.get(5)).isEqualTo(mBluetoothMediaDevice3); - assertThat(mMediaDevices.get(6)).isEqualTo(mInfoMediaDevice3); + assertThat(mMediaDevices.get(5)).isEqualTo(mInfoMediaDevice3); + assertThat(mMediaDevices.get(6)).isEqualTo(mPhoneMediaDevice); } // 1.mInfoMediaDevice1: Last Selected device @@ -376,7 +410,7 @@ public class MediaDeviceTest { // 5.mBluetoothMediaDevice2: * 4 times usage not connected // 6.mBluetoothMediaDevice3: * 1 time usage // 7.mPhoneMediaDevice: * 0 time usage - // Order: 7 -> 1 -> 3 -> 6 -> 4 -> 2 -> 5 + // Order: 6 -> 1 -> 3 -> 4 -> 7 -> 2 -> 5 @Test public void compareTo_mixedDevices_connectDeviceFirst() { when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass); @@ -402,11 +436,11 @@ public class MediaDeviceTest { mInfoMediaDevice1.connect(); Collections.sort(mMediaDevices, COMPARATOR); - assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice3); assertThat(mMediaDevices.get(1)).isEqualTo(mInfoMediaDevice1); assertThat(mMediaDevices.get(2)).isEqualTo(mInfoMediaDevice2); - assertThat(mMediaDevices.get(3)).isEqualTo(mBluetoothMediaDevice3); - assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice3); + assertThat(mMediaDevices.get(3)).isEqualTo(mInfoMediaDevice3); + assertThat(mMediaDevices.get(4)).isEqualTo(mPhoneMediaDevice); assertThat(mMediaDevices.get(5)).isEqualTo(mBluetoothMediaDevice1); assertThat(mMediaDevices.get(6)).isEqualTo(mBluetoothMediaDevice2); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java index 4c5cd9682b0f..6f265dd603e5 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java @@ -17,6 +17,7 @@ package com.android.settingslib.media; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_USB_DEVICE; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; @@ -95,9 +96,9 @@ public class PhoneMediaDeviceTest { when(mInfo.getName()).thenReturn(deviceName); assertThat(mPhoneMediaDevice.getName()) - .isEqualTo(deviceName); + .isEqualTo(mContext.getString(R.string.media_transfer_wired_device_name)); - when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADSET); + when(mInfo.getType()).thenReturn(TYPE_USB_DEVICE); assertThat(mPhoneMediaDevice.getName()) .isEqualTo(deviceName); diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp index d67bd8da844f..9d042a4e15f6 100644 --- a/packages/SettingsProvider/Android.bp +++ b/packages/SettingsProvider/Android.bp @@ -34,6 +34,7 @@ android_test { ], static_libs: [ "androidx.test.rules", + "mockito-target-minus-junit4", "SettingsLibDisplayDensityUtils", "platform-test-annotations", "truth-prebuilt", diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml index 839899ecaa31..04d3f9486354 100644 --- a/packages/SettingsProvider/AndroidManifest.xml +++ b/packages/SettingsProvider/AndroidManifest.xml @@ -21,5 +21,10 @@ android:singleUser="true" android:initOrder="100" android:visibleToInstantApps="true" /> + + <service + android:name="WriteFallbackSettingsFilesJobService" + android:permission="android.permission.BIND_JOB_SERVICE" + android:exported="true"/> </application> </manifest> diff --git a/packages/SettingsProvider/OWNERS b/packages/SettingsProvider/OWNERS index 2054129506bc..b2ac4f43e845 100644 --- a/packages/SettingsProvider/OWNERS +++ b/packages/SettingsProvider/OWNERS @@ -1,3 +1,5 @@ hackbod@google.com +narayan@google.com svetoslavganov@google.com -moltmann@google.com +schfan@google.com +toddke@google.com diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index b6e31d26a088..d023d98f2b73 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -48,6 +48,8 @@ import java.util.Locale; public class SettingsHelper { private static final String TAG = "SettingsHelper"; private static final String SILENT_RINGTONE = "_silent"; + private static final String SETTINGS_REPLACED_KEY = "backup_skip_user_facing_data"; + private static final String SETTING_ORIGINAL_KEY_SUFFIX = "_original"; private static final float FLOAT_TOLERANCE = 0.01f; private Context mContext; @@ -121,6 +123,10 @@ public class SettingsHelper { */ public void restoreValue(Context context, ContentResolver cr, ContentValues contentValues, Uri destination, String name, String value, int restoredFromSdkInt) { + if (isReplacedSystemSetting(name)) { + return; + } + // Will we need a post-restore broadcast for this element? String oldValue = null; boolean sendBroadcast = false; @@ -203,7 +209,32 @@ public class SettingsHelper { } } // Return the original value - return value; + return isReplacedSystemSetting(name) ? getRealValueForSystemSetting(name) : value; + } + + /** + * The setting value might have been replaced temporarily. If that's the case, return the real + * value instead of the temporary one. + */ + @VisibleForTesting + public String getRealValueForSystemSetting(String setting) { + return Settings.System.getString(mContext.getContentResolver(), + setting + SETTING_ORIGINAL_KEY_SUFFIX); + } + + @VisibleForTesting + public boolean isReplacedSystemSetting(String setting) { + // This list should not be modified. + if (!Settings.System.MASTER_MONO.equals(setting) + && !Settings.System.SCREEN_OFF_TIMEOUT.equals(setting)) { + return false; + } + // If this flag is set, values for the system settings from the list above have been + // temporarily replaced. We don't want to back up the temporary value or run restore for + // such settings. + // TODO(154822946): Remove this logic in the next release. + return Settings.Secure.getInt(mContext.getContentResolver(), SETTINGS_REPLACED_KEY, + /* def */ 0) != 0; } /** diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 2245ee4f2821..94509ddcc407 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -23,12 +23,16 @@ import static android.os.Process.SYSTEM_UID; import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY; +import static com.android.providers.settings.SettingsState.FALLBACK_FILE_SUFFIX; + import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.backup.BackupManager; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentProvider; @@ -55,12 +59,14 @@ import android.os.Build; import android.os.Bundle; import android.os.DropBoxManager; import android.os.Environment; +import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.IUserRestrictionsListener; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; +import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteCallback; import android.os.RemoteException; @@ -95,6 +101,7 @@ import libcore.util.HexEncoding; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.PrintWriter; import java.nio.ByteBuffer; import java.security.InvalidKeyException; @@ -154,9 +161,11 @@ public class SettingsProvider extends ContentProvider { private static final String LOG_TAG = "SettingsProvider"; - private static final String TABLE_SYSTEM = "system"; - private static final String TABLE_SECURE = "secure"; - private static final String TABLE_GLOBAL = "global"; + public static final String TABLE_SYSTEM = "system"; + public static final String TABLE_SECURE = "secure"; + public static final String TABLE_GLOBAL = "global"; + public static final String TABLE_SSAID = "ssaid"; + public static final String TABLE_CONFIG = "config"; // Old tables no longer exist. private static final String TABLE_FAVORITES = "favorites"; @@ -205,6 +214,10 @@ public class SettingsProvider extends ContentProvider { public static final String RESULT_ROWS_DELETED = "result_rows_deleted"; public static final String RESULT_SETTINGS_LIST = "result_settings_list"; + // Used for scheduling jobs to make a copy for the settings files + public static final int WRITE_FALLBACK_SETTINGS_FILES_JOB_ID = 1; + public static final long ONE_DAY_INTERVAL_MILLIS = 24 * 60 * 60 * 1000L; + // Overlay specified settings whitelisted for Instant Apps private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>(); private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>(); @@ -2484,6 +2497,68 @@ public class SettingsProvider extends ContentProvider { } } + /** + * Schedule the job service to make a copy of all the settings files. + */ + public void scheduleWriteFallbackFilesJob() { + final Context context = getContext(); + final JobScheduler jobScheduler = + (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + if (jobScheduler == null) { + // Might happen: SettingsProvider is created before JobSchedulerService in system server + return; + } + // Check if the job is already scheduled. If so, skip scheduling another one + if (jobScheduler.getPendingJob(WRITE_FALLBACK_SETTINGS_FILES_JOB_ID) != null) { + return; + } + // Back up all settings files + final PersistableBundle bundle = new PersistableBundle(); + final File globalSettingsFile = mSettingsRegistry.getSettingsFile( + makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM)); + final File systemSettingsFile = mSettingsRegistry.getSettingsFile( + makeKey(SETTINGS_TYPE_SYSTEM, UserHandle.USER_SYSTEM)); + final File secureSettingsFile = mSettingsRegistry.getSettingsFile( + makeKey(SETTINGS_TYPE_SECURE, UserHandle.USER_SYSTEM)); + final File ssaidSettingsFile = mSettingsRegistry.getSettingsFile( + makeKey(SETTINGS_TYPE_SSAID, UserHandle.USER_SYSTEM)); + final File configSettingsFile = mSettingsRegistry.getSettingsFile( + makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM)); + bundle.putString(TABLE_GLOBAL, globalSettingsFile.getAbsolutePath()); + bundle.putString(TABLE_SYSTEM, systemSettingsFile.getAbsolutePath()); + bundle.putString(TABLE_SECURE, secureSettingsFile.getAbsolutePath()); + bundle.putString(TABLE_SSAID, ssaidSettingsFile.getAbsolutePath()); + bundle.putString(TABLE_CONFIG, configSettingsFile.getAbsolutePath()); + // Schedule the job to write the fallback files, once daily when phone is charging + jobScheduler.schedule(new JobInfo.Builder(WRITE_FALLBACK_SETTINGS_FILES_JOB_ID, + new ComponentName(context, WriteFallbackSettingsFilesJobService.class)) + .setExtras(bundle) + .setPeriodic(ONE_DAY_INTERVAL_MILLIS) + .setRequiresCharging(true) + .setPersisted(true) + .build()); + } + + /** + * For each file in the given list, if it exists, copy it to a back up file. Ignore failures. + * @param filePaths List of paths of files that need to be backed up + */ + public static void writeFallBackSettingsFiles(List<String> filePaths) { + final int numFiles = filePaths.size(); + for (int i = 0; i < numFiles; i++) { + final String filePath = filePaths.get(i); + final File originalFile = new File(filePath); + if (SettingsState.stateFileExists(originalFile)) { + final File fallBackFile = new File(filePath + FALLBACK_FILE_SUFFIX); + try { + FileUtils.copy(originalFile, fallBackFile); + } catch (IOException ex) { + Slog.w(LOG_TAG, "Failed to write fallback file for: " + filePath); + } + } + } + } + final class SettingsRegistry { private static final String DROPBOX_TAG_USERLOG = "restricted_profile_ssaid"; @@ -3431,6 +3506,7 @@ public class SettingsProvider extends ContentProvider { case MSG_NOTIFY_DATA_CHANGED: { mBackupManager.dataChanged(); + scheduleWriteFallbackFilesJob(); } break; } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 6b8219ea9c70..6678cf6f1033 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.Binder; import android.os.Build; +import android.os.FileUtils; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -101,6 +102,8 @@ final class SettingsState { public static final int VERSION_UNDEFINED = -1; + public static final String FALLBACK_FILE_SUFFIX = ".fallback"; + private static final String TAG_SETTINGS = "settings"; private static final String TAG_SETTING = "setting"; private static final String ATTR_PACKAGE = "package"; @@ -266,7 +269,7 @@ final class SettingsState { public SettingsState(Context context, Object lock, File file, int key, int maxBytesPerAppPackage, Looper looper) { // It is important that we use the same lock as the settings provider - // to ensure multiple mutations on this state are atomicaly persisted + // to ensure multiple mutations on this state are atomically persisted // as the async persistence should be blocked while we make changes. mContext = context; mLock = lock; @@ -998,24 +1001,56 @@ final class SettingsState { } @GuardedBy("mLock") - private void readStateSyncLocked() { + private void readStateSyncLocked() throws IllegalStateException { FileInputStream in; + AtomicFile file = new AtomicFile(mStatePersistFile); try { - in = new AtomicFile(mStatePersistFile).openRead(); + in = file.openRead(); } catch (FileNotFoundException fnfe) { - Slog.i(LOG_TAG, "No settings state " + mStatePersistFile); + Slog.w(LOG_TAG, "No settings state " + mStatePersistFile); logSettingsDirectoryInformation(mStatePersistFile); addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null); return; } + if (parseStateFromXmlStreamLocked(in)) { + return; + } + + // Settings file exists but is corrupted. Retry with the fallback file + final File statePersistFallbackFile = new File( + mStatePersistFile.getAbsolutePath() + FALLBACK_FILE_SUFFIX); + Slog.i(LOG_TAG, "Failed parsing settings file: " + mStatePersistFile + + ", retrying with fallback file: " + statePersistFallbackFile); + try { + in = new AtomicFile(statePersistFallbackFile).openRead(); + } catch (FileNotFoundException fnfe) { + final String message = "No fallback file found for: " + mStatePersistFile; + Slog.wtf(LOG_TAG, message); + throw new IllegalStateException(message); + } + if (parseStateFromXmlStreamLocked(in)) { + // Parsed state from fallback file. Restore original file with fallback file + try { + FileUtils.copy(statePersistFallbackFile, mStatePersistFile); + } catch (IOException ignored) { + // Failed to copy, but it's okay because we already parsed states from fallback file + } + } else { + final String message = "Failed parsing settings file: " + mStatePersistFile; + Slog.wtf(LOG_TAG, message); + throw new IllegalStateException(message); + } + } + + @GuardedBy("mLock") + private boolean parseStateFromXmlStreamLocked(FileInputStream in) { try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, StandardCharsets.UTF_8.name()); parseStateLocked(parser); + return true; } catch (XmlPullParserException | IOException e) { - String message = "Failed parsing settings file: " + mStatePersistFile; - Slog.wtf(LOG_TAG, message); - throw new IllegalStateException(message, e); + return false; } finally { IoUtils.closeQuietly(in); } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java new file mode 100644 index 000000000000..6e5b8890438d --- /dev/null +++ b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.providers.settings; + +import static com.android.providers.settings.SettingsProvider.TABLE_CONFIG; +import static com.android.providers.settings.SettingsProvider.TABLE_GLOBAL; +import static com.android.providers.settings.SettingsProvider.TABLE_SECURE; +import static com.android.providers.settings.SettingsProvider.TABLE_SSAID; +import static com.android.providers.settings.SettingsProvider.TABLE_SYSTEM; +import static com.android.providers.settings.SettingsProvider.WRITE_FALLBACK_SETTINGS_FILES_JOB_ID; + +import android.app.job.JobParameters; +import android.app.job.JobService; + +import java.util.ArrayList; +import java.util.List; + +/** + * JobService to make a copy of a list of files, given their paths. + */ +public class WriteFallbackSettingsFilesJobService extends JobService { + @Override + public boolean onStartJob(final JobParameters params) { + switch (params.getJobId()) { + case WRITE_FALLBACK_SETTINGS_FILES_JOB_ID: + final List<String> settingsFiles = new ArrayList<>(); + settingsFiles.add(params.getExtras().getString(TABLE_GLOBAL, "")); + settingsFiles.add(params.getExtras().getString(TABLE_SYSTEM, "")); + settingsFiles.add(params.getExtras().getString(TABLE_SECURE, "")); + settingsFiles.add(params.getExtras().getString(TABLE_SSAID, "")); + settingsFiles.add(params.getExtras().getString(TABLE_CONFIG, "")); + SettingsProvider.writeFallBackSettingsFiles(settingsFiles); + return true; + default: + return false; + } + } + + @Override + public boolean onStopJob(JobParameters params) { + return false; + } + +} diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 03f6df0d5d2d..f5589d713bf7 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -296,6 +296,7 @@ public class SettingsBackupTest { Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, Settings.Global.HDMI_CONTROL_ENABLED, + Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, Settings.Global.HIDDEN_API_POLICY, @@ -419,7 +420,6 @@ public class SettingsBackupTest { Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS, Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, Settings.Global.SAFE_BOOT_DISALLOWED, Settings.Global.SELINUX_STATUS, Settings.Global.SELINUX_UPDATE_CONTENT_URL, diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java index d112facc2b0e..7baa2266756f 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java @@ -18,18 +18,79 @@ package com.android.providers.settings; import static junit.framework.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.media.AudioManager; +import android.net.Uri; import android.os.LocaleList; +import android.telephony.TelephonyManager; import androidx.test.runner.AndroidJUnit4; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; /** * Tests for the SettingsHelperTest */ @RunWith(AndroidJUnit4.class) public class SettingsHelperTest { + private static final String SETTING_KEY = "setting_key"; + private static final String SETTING_VALUE = "setting_value"; + private static final String SETTING_REAL_VALUE = "setting_real_value"; + + private SettingsHelper mSettingsHelper; + + @Mock private Context mContext; + @Mock private ContentResolver mContentResolver; + @Mock private AudioManager mAudioManager; + @Mock private TelephonyManager mTelephonyManager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mContext.getSystemService(eq(Context.AUDIO_SERVICE))).thenReturn(mAudioManager); + when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE))).thenReturn( + mTelephonyManager); + + mSettingsHelper = spy(new SettingsHelper(mContext)); + } + + @Test + public void testOnBackupValue_settingReplaced_returnsRealValue() { + when(mSettingsHelper.isReplacedSystemSetting(eq(SETTING_KEY))).thenReturn(true); + doReturn(SETTING_REAL_VALUE).when(mSettingsHelper).getRealValueForSystemSetting( + eq(SETTING_KEY)); + + assertEquals(SETTING_REAL_VALUE, mSettingsHelper.onBackupValue(SETTING_KEY, SETTING_VALUE)); + } + + @Test + public void testGetRealValue_settingNotReplaced_returnsSameValue() { + when(mSettingsHelper.isReplacedSystemSetting(eq(SETTING_KEY))).thenReturn(false); + + assertEquals(SETTING_VALUE, mSettingsHelper.onBackupValue(SETTING_KEY, SETTING_VALUE)); + } + + @Test + public void testRestoreValue_settingReplaced_doesNotRestore() { + when(mSettingsHelper.isReplacedSystemSetting(eq(SETTING_KEY))).thenReturn(true); + mSettingsHelper.restoreValue(mContext, mContentResolver, new ContentValues(), Uri.EMPTY, + SETTING_KEY, SETTING_VALUE, /* restoredFromSdkInt */ 0); + + verifyZeroInteractions(mContentResolver); + } + @Test public void testResolveLocales() throws Exception { // Empty string from backup server diff --git a/packages/SimAppDialog/res/values-af/strings.xml b/packages/SimAppDialog/res/values-af/strings.xml new file mode 100644 index 000000000000..143bc67d0794 --- /dev/null +++ b/packages/SimAppDialog/res/values-af/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM-programdialoog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktiveer mobiele diens"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Jy sal die <xliff:g id="ID_1">%1$s</xliff:g>-program moet installeer om jou nuwe SIM behoorlik te laat werk"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Jy sal die diensverskafferprogram moet installeer om jou nuwe SIM behoorlik te laat werk"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Nie nou nie"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Laai program af"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-am/strings.xml b/packages/SimAppDialog/res/values-am/strings.xml new file mode 100644 index 000000000000..a2fc5833dab7 --- /dev/null +++ b/packages/SimAppDialog/res/values-am/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"የሲም መተግበሪያ መገናኛ"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"የሞባይል አገልግሎትን አግብር"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"አዲሱ የእርስዎ ሲም በአግባቡ እንዲሰራ ለማድረግ የ<xliff:g id="ID_1">%1$s</xliff:g> መተግበሪያውን መጫን አለብዎት"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"አዲሱ የእርስዎ ሲም በአግባቡ እንዲሰራ ለማድረግ የአገልግሎት አቅራቢ መተግበሪያውን መጫን አለብዎት"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"አሁን አይደለም"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"መተግበሪያን አውርድ"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ar/strings.xml b/packages/SimAppDialog/res/values-ar/strings.xml new file mode 100644 index 000000000000..4087d1e17ec7 --- /dev/null +++ b/packages/SimAppDialog/res/values-ar/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"تفعيل خدمة الجوّال"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"لتعمل شريحة SIM الجديدة بشكل سليم، ستحتاج إلى تثبيت تطبيق <xliff:g id="ID_1">%1$s</xliff:g>."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"لتعمل شريحة SIM الجديدة بشكل سليم، ستحتاج إلى تثبيت تطبيق مشغّل شبكة الجوّال."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"لاحقًا"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"تنزيل التطبيق"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-as/strings.xml b/packages/SimAppDialog/res/values-as/strings.xml new file mode 100644 index 000000000000..8002c3fe171a --- /dev/null +++ b/packages/SimAppDialog/res/values-as/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"ম’বাইল সেৱা সক্ৰিয় কৰক"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"আপোনাৰ নতুন ছিমখনে ভালকৈ কাম কৰিবলৈ হ’লে আপুনি <xliff:g id="ID_1">%1$s</xliff:g> এপ্টো ইনষ্টল কৰিব লাগিব"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"আপোনাৰ নতুন ছিমখনে ভালকৈ কাম কৰিবলৈ হ’লে আপুনি বাহকৰ এপ্টো ইনষ্টল কৰিব লাগিব"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"এতিয়া নহয়"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"এপ্টো ডাউনল’ড কৰক"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-az/strings.xml b/packages/SimAppDialog/res/values-az/strings.xml new file mode 100644 index 000000000000..f96ed7d02102 --- /dev/null +++ b/packages/SimAppDialog/res/values-az/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim Tətbiq Dialoqu"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Mobil xidməti aktiv edin"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Yeni SIM kartınızın düzgün işləməsi üçün <xliff:g id="ID_1">%1$s</xliff:g> tətbiqini yükləməlisiniz"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Yeni SIM kartınızın düzgün işləməsi üçün operator tətbiqini yükləməlisiniz"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"İndi yox"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Tətbiqi endirin"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml b/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000000..f7771c5fbe0e --- /dev/null +++ b/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivirajte mobilnu uslugu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Da bi nova SIM kartica ispravno radila, treba da instalirate aplikaciju <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Da bi nova SIM kartica ispravno radila, treba da instalirate aplikaciju mobilnog operatera"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ne sada"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Preuzmi aplikaciju"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-be/strings.xml b/packages/SimAppDialog/res/values-be/strings.xml new file mode 100644 index 000000000000..7207f58f02cd --- /dev/null +++ b/packages/SimAppDialog/res/values-be/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Дыялогавае акно праграмы SIM-карты"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Уключыце мабільную сувязь"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Каб ваша новая SIM-карта працавала належным чынам, вам трэба ўсталяваць праграму \"<xliff:g id="ID_1">%1$s</xliff:g>\""</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Каб ваша новая SIM-карта працавала належным чынам, вам трэба ўсталяваць праграму ад аператара"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Не зараз"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Спампаваць праграму"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-bg/strings.xml b/packages/SimAppDialog/res/values-bg/strings.xml new file mode 100644 index 000000000000..a7b66028c1d1 --- /dev/null +++ b/packages/SimAppDialog/res/values-bg/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Активиране на мобилната услуга"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"За да работи правилно новата ви SIM карта, трябва да инсталирате приложението <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"За да работи правилно новата ви SIM карта, трябва да инсталирате приложението на оператора"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Не сега"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Изтегляне на приложението"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-bn/strings.xml b/packages/SimAppDialog/res/values-bn/strings.xml new file mode 100644 index 000000000000..0659d3763d1c --- /dev/null +++ b/packages/SimAppDialog/res/values-bn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"সিম অ্যাপ ডায়ালগ"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"মোবাইল পরিষেবা চালু করুন"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"আপনার নতুন সিম যাতে সঠিকভাবে কাজ করে, তার জন্য আপনাকে <xliff:g id="ID_1">%1$s</xliff:g> অ্যাপ ইনস্টল করতে হবে"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"আপনার নতুন সিম যাতে সঠিকভাবে কাজ করে, তার জন্য আপনাকে পরিষেবা প্রদানকারীর অ্যাপ ইনস্টল করতে হবে"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"এখন নয়"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"অ্যাপ ডাউনলোড করুন"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-bs/strings.xml b/packages/SimAppDialog/res/values-bs/strings.xml new file mode 100644 index 000000000000..b568f7553cf1 --- /dev/null +++ b/packages/SimAppDialog/res/values-bs/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivirajte mobilnu uslugu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Da bi nova SIM kartica ispravno funkcionirala, morate instalirati aplikaciju <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Da bi nova SIM kartica ispravno funkcionirala, morate instalirati aplikaciju mobilnog operatera"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ne sada"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Preuzmi aplikaciju"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ca/strings.xml b/packages/SimAppDialog/res/values-ca/strings.xml new file mode 100644 index 000000000000..731f0343eed9 --- /dev/null +++ b/packages/SimAppDialog/res/values-ca/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activa el servei mòbil"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Si vols que la teva SIM nova funcioni correctament, has d\'instal·lar l\'aplicació <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Si vols que la teva SIM nova funcioni correctament, has d\'instal·lar l\'aplicació de l\'operador"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ara no"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Baixa l\'aplicació"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-cs/strings.xml b/packages/SimAppDialog/res/values-cs/strings.xml new file mode 100644 index 000000000000..775fa792b719 --- /dev/null +++ b/packages/SimAppDialog/res/values-cs/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Dialogové okno aplikace SIM karty"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivovat mobilní službu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Aby vaše nová SIM karta fungovala správně, je třeba nainstalovat aplikaci <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Aby vaše nová SIM karta fungovala správně, je třeba nainstalovat aplikaci operátora"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Teď ne"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Stáhnout aplikaci"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-da/strings.xml b/packages/SimAppDialog/res/values-da/strings.xml new file mode 100644 index 000000000000..44528f773802 --- /dev/null +++ b/packages/SimAppDialog/res/values-da/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Dialogboks for app til SIM-kort"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivér mobilnetværk"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Du skal installere appen <xliff:g id="ID_1">%1$s</xliff:g>, før dit nye SIM-kort kan fungere korrekt."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Du skal installere appen for dit mobilselskab, før dit nye SIM-kort kan fungere korrekt."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ikke nu"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Download app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-de/strings.xml b/packages/SimAppDialog/res/values-de/strings.xml new file mode 100644 index 000000000000..7edecd4c7451 --- /dev/null +++ b/packages/SimAppDialog/res/values-de/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM-App-Dialogfeld"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Mobilfunkdienst aktivieren"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Damit deine neue SIM-Karte richtig funktioniert, musst du die <xliff:g id="ID_1">%1$s</xliff:g> App installieren"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Damit deine neue SIM-Karte richtig funktioniert, musst du die Mobilfunkanbieter-App installieren"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Nicht jetzt"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"App herunterladen"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-el/strings.xml b/packages/SimAppDialog/res/values-el/strings.xml new file mode 100644 index 000000000000..71700dc24192 --- /dev/null +++ b/packages/SimAppDialog/res/values-el/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Ενεργ. υπηρεσίας κιν. τηλεφ."</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Για την εύρυθμη λειτουργία της νέας σας SIM, θα πρέπει να εγκαταστήσετε την εφαρμογή <xliff:g id="ID_1">%1$s</xliff:g>."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Για εύρυθμη λειτουργία της νέας SIM, πρέπει να εγκαταστήσετε την εφαρμογή της εταιρείας κιν. τηλεφ."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Όχι τώρα"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Λήψη εφαρμογής"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-en-rAU/strings.xml b/packages/SimAppDialog/res/values-en-rAU/strings.xml new file mode 100644 index 000000000000..6236a8f64850 --- /dev/null +++ b/packages/SimAppDialog/res/values-en-rAU/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim app dialogue"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activate mobile service"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"To get your new SIM working properly, you\'ll need to install the <xliff:g id="ID_1">%1$s</xliff:g> app"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"To get your new SIM working properly, you\'ll need to install the operator app"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Not now"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Download app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-en-rCA/strings.xml b/packages/SimAppDialog/res/values-en-rCA/strings.xml new file mode 100644 index 000000000000..6236a8f64850 --- /dev/null +++ b/packages/SimAppDialog/res/values-en-rCA/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim app dialogue"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activate mobile service"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"To get your new SIM working properly, you\'ll need to install the <xliff:g id="ID_1">%1$s</xliff:g> app"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"To get your new SIM working properly, you\'ll need to install the operator app"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Not now"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Download app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-en-rGB/strings.xml b/packages/SimAppDialog/res/values-en-rGB/strings.xml new file mode 100644 index 000000000000..6236a8f64850 --- /dev/null +++ b/packages/SimAppDialog/res/values-en-rGB/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim app dialogue"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activate mobile service"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"To get your new SIM working properly, you\'ll need to install the <xliff:g id="ID_1">%1$s</xliff:g> app"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"To get your new SIM working properly, you\'ll need to install the operator app"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Not now"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Download app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-en-rIN/strings.xml b/packages/SimAppDialog/res/values-en-rIN/strings.xml new file mode 100644 index 000000000000..6236a8f64850 --- /dev/null +++ b/packages/SimAppDialog/res/values-en-rIN/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim app dialogue"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activate mobile service"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"To get your new SIM working properly, you\'ll need to install the <xliff:g id="ID_1">%1$s</xliff:g> app"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"To get your new SIM working properly, you\'ll need to install the operator app"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Not now"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Download app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-en-rXC/strings.xml b/packages/SimAppDialog/res/values-en-rXC/strings.xml new file mode 100644 index 000000000000..471fdd00ddf3 --- /dev/null +++ b/packages/SimAppDialog/res/values-en-rXC/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activate mobile service"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"To get your new SIM working properly, you\'ll need to install the <xliff:g id="ID_1">%1$s</xliff:g> app"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"To get your new SIM working properly, you\'ll need to install the carrier app"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Not now"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Download app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-es-rUS/strings.xml b/packages/SimAppDialog/res/values-es-rUS/strings.xml new file mode 100644 index 000000000000..9543bd15eb6f --- /dev/null +++ b/packages/SimAppDialog/res/values-es-rUS/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activa serv. de datos móviles"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Para que la tarjeta SIM funcione correctamente, deberás instalar la app de <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para que la tarjeta SIM funcione correctamente, deberás instalar la app del proveedor"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ahora no"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Descargar app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-es/strings.xml b/packages/SimAppDialog/res/values-es/strings.xml new file mode 100644 index 000000000000..efc42e494150 --- /dev/null +++ b/packages/SimAppDialog/res/values-es/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Cuadro de diálogo de la aplicación de SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activar servicio móvil"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Para que tu nueva SIM funcione correctamente, tienes que instalar la aplicación <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para que tu nueva SIM funcione correctamente, tienes que instalar la aplicación del operador"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ahora no"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Descargar aplicación"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-et/strings.xml b/packages/SimAppDialog/res/values-et/strings.xml new file mode 100644 index 000000000000..6efac988539a --- /dev/null +++ b/packages/SimAppDialog/res/values-et/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Mobiilsideteenuse aktiveerimine"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Selleks, et uus SIM-kaart õigesti tööle hakkaks, peate installima operaatori <xliff:g id="ID_1">%1$s</xliff:g> rakenduse"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Selleks, et uus SIM-kaart õigesti tööle hakkaks, peate installima operaatori rakenduse"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Mitte praegu"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Laadi rakendus alla"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-eu/strings.xml b/packages/SimAppDialog/res/values-eu/strings.xml new file mode 100644 index 000000000000..ffd62f74b039 --- /dev/null +++ b/packages/SimAppDialog/res/values-eu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim aplikazioaren leihoa"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktibatu mugikorreko zerbitzua"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"SIM berriak behar bezala funtziona dezan, <xliff:g id="ID_1">%1$s</xliff:g> aplikazioa instalatu behar duzu"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"SIM berriak behar bezala funtziona dezan, operadorearen aplikazioa instalatu behar duzu"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Orain ez"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Deskargatu aplikazioa"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-fa/strings.xml b/packages/SimAppDialog/res/values-fa/strings.xml new file mode 100644 index 000000000000..7eb87dddf41d --- /dev/null +++ b/packages/SimAppDialog/res/values-fa/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"کادر گفتگوی برنامه Sim"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"سرویس دستگاه همراه را فعال کنید"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"برای اینکه سیمکارت جدیدتان بهدرستی کار کند، باید برنامه <xliff:g id="ID_1">%1$s</xliff:g> را نصب کنید"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"برای اینکه سیمکارت جدیدتان بهدرستی کار کند، باید برنامه شرکت مخابراتی را نصب کنید"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"الآن نه"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"بارگیری برنامه"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-fi/strings.xml b/packages/SimAppDialog/res/values-fi/strings.xml new file mode 100644 index 000000000000..a0535c5d2fb4 --- /dev/null +++ b/packages/SimAppDialog/res/values-fi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivoi mobiilipalvelu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Jotta uusi SIM-korttisi toimii kunnolla, sinun on asennettava <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Jotta uusi SIM-korttisi toimii kunnolla, sinun on asennettava operaattorin sovellus"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ei nyt"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Lataa sovellus"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-fr-rCA/strings.xml b/packages/SimAppDialog/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000000..b6075855a3bb --- /dev/null +++ b/packages/SimAppDialog/res/values-fr-rCA/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Boîte de dialogue de l\'application SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activer le service cellulaire"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Pour que le nouveau module SIM fonctionne correctement, vous devez installer l\'application <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Pour que le nouveau module SIM fonctionne, vous devez installer l\'appli du fournisseur de services"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Pas maintenant"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Télécharger l\'application"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-fr/strings.xml b/packages/SimAppDialog/res/values-fr/strings.xml new file mode 100644 index 000000000000..b3fbdcca4054 --- /dev/null +++ b/packages/SimAppDialog/res/values-fr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activer service données mobiles"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Pour que la nouvelle carte SIM fonctionne correctement, vous devez installer l\'application <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Pour que la nouvelle carte SIM fonctionne correctement, vous devez installer l\'appli de l\'opérateur"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Pas maintenant"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Télécharger l\'application"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-gl/strings.xml b/packages/SimAppDialog/res/values-gl/strings.xml new file mode 100644 index 000000000000..fba3d1c7e39c --- /dev/null +++ b/packages/SimAppDialog/res/values-gl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activa o servizo móbil"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Para conseguir que a túa SIM nova funcione correctamente, deberás instalar a aplicación <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para conseguir que a túa SIM nova funcione correctamente, deberás instalar a aplicación do operador"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Agora non"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Descargar aplicación"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-gu/strings.xml b/packages/SimAppDialog/res/values-gu/strings.xml new file mode 100644 index 000000000000..deb302016d53 --- /dev/null +++ b/packages/SimAppDialog/res/values-gu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"મોબાઇલ સેવાને સક્રિય કરો"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"તમારું નવું સિમ યોગ્ય રીતે કામ કરે તે માટે, તમારે <xliff:g id="ID_1">%1$s</xliff:g> ઍપ ઇન્સ્ટૉલ કરવાની જરૂર રહેશે"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"તમારું નવું સિમ યોગ્ય રીતે કામ કરે તે માટે, તમારે મોબાઇલ ઑપરેટરની ઍપ ઇન્સ્ટૉલ કરવાની જરૂર રહેશે"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"હમણાં નહીં"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ઍપ ડાઉનલોડ કરો"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-hi/strings.xml b/packages/SimAppDialog/res/values-hi/strings.xml new file mode 100644 index 000000000000..f5e3edfc0682 --- /dev/null +++ b/packages/SimAppDialog/res/values-hi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"सिम ऐप डायलॉग"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"माेबाइल सेवा चालू करें"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"नया सिम ठीक से काम करे, इसके लिए आपको <xliff:g id="ID_1">%1$s</xliff:g> ऐप्लिकेशन इंस्टॉल करना होगा"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"नया सिम ठीक से काम करे, इसके लिए आपको मोबाइल और इंटरनेट सेवा देने वाली कंपनी का ऐप डाउनलोड करना होगा"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"अभी नहीं"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ऐप्लिकेशन डाउनलोड करें"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-hr/strings.xml b/packages/SimAppDialog/res/values-hr/strings.xml new file mode 100644 index 000000000000..5e6d4f8554a4 --- /dev/null +++ b/packages/SimAppDialog/res/values-hr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivirajte mobilnu uslugu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Da bi vaš novi SIM ispravno radio, morat ćete instalirati aplikaciju <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Da bi vaš novi SIM ispravno radio, morat ćete instalirati aplikaciju mobilnog operatera"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ne sad"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Preuzmi aplikaciju"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-hu/strings.xml b/packages/SimAppDialog/res/values-hu/strings.xml new file mode 100644 index 000000000000..c96ce8382c69 --- /dev/null +++ b/packages/SimAppDialog/res/values-hu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM-alkalmazás dialógusa"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Mobilszolgáltatás aktiválása"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Az új SIM-kártya megfelelő működéséhez telepítenie kell a(z) <xliff:g id="ID_1">%1$s</xliff:g> alkalmazást"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Az új SIM-kártya megfelelő működéséhez telepítenie kell a szolgáltató alkalmazását"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Most nem"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Alkalmazás letöltése"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-hy/strings.xml b/packages/SimAppDialog/res/values-hy/strings.xml new file mode 100644 index 000000000000..fad04359070a --- /dev/null +++ b/packages/SimAppDialog/res/values-hy/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Ակտիվացրեք բջջային կապը"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Նոր SIM քարտի պատշաճ աշխատանքն ապահովելու համար տեղադրեք <xliff:g id="ID_1">%1$s</xliff:g> օպերատորի հավելվածը"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Նոր SIM քարտի պատշաճ աշխատանքն ապահովելու համար տեղադրեք օպերատորի հավելվածը"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ոչ հիմա"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Ներբեռնել հավելվածը"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-in/strings.xml b/packages/SimAppDialog/res/values-in/strings.xml new file mode 100644 index 000000000000..fde91433c219 --- /dev/null +++ b/packages/SimAppDialog/res/values-in/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Dialog Aplikasi SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktifkan layanan seluler"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Agar SIM baru berfungsi dengan baik, Anda harus menginstal aplikasi <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Agar SIM baru berfungsi dengan baik, Anda harus menginstal aplikasi operator"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Lain kali"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Download aplikasi"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-is/strings.xml b/packages/SimAppDialog/res/values-is/strings.xml new file mode 100644 index 000000000000..7074140179ec --- /dev/null +++ b/packages/SimAppDialog/res/values-is/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Gluggi SIM-forrits"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Virkja farsímaþjónustu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Til að nýja SIM-kortið þitt virki eins og vera ber þarftu að setja upp forritið <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Til að nýja SIM-kortið þitt virki eins og vera ber þarftu að setja upp forrit frá símafyrirtækinu"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ekki núna"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Sækja forritið"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-it/strings.xml b/packages/SimAppDialog/res/values-it/strings.xml new file mode 100644 index 000000000000..e597fa2269ef --- /dev/null +++ b/packages/SimAppDialog/res/values-it/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Attiva il servizio dati mobile"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Affinché la tua nuova SIM possa funzionare correttamente, devi installare l\'app <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Affinché la tua nuova SIM possa funzionare correttamente, devi installare l\'app dell\'operatore"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Non ora"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Scarica app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-iw/strings.xml b/packages/SimAppDialog/res/values-iw/strings.xml new file mode 100644 index 000000000000..3681911f953d --- /dev/null +++ b/packages/SimAppDialog/res/values-iw/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"תיבת דו-שיח של אפליקציית כרטיס ה-SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"הפעלה של השירות הסלולרי"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"כדי שכרטיס ה-SIM החדש יפעל כראוי, צריך להתקין את האפליקציה <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"כדי שכרטיס ה-SIM החדש יפעל כראוי, צריך להתקין את אפליקציית הספק"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"לא עכשיו"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"הורדת האפליקציה"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ja/strings.xml b/packages/SimAppDialog/res/values-ja/strings.xml new file mode 100644 index 000000000000..209ed2963fc0 --- /dev/null +++ b/packages/SimAppDialog/res/values-ja/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM アプリのダイアログ"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"モバイル サービスを有効にする"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"新しい SIM を正常に機能させるには、<xliff:g id="ID_1">%1$s</xliff:g> アプリをインストールする必要があります"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"新しい SIM を正常に機能させるには、携帯通信会社のアプリをインストールする必要があります"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"後で"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"アプリをダウンロード"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ka/strings.xml b/packages/SimAppDialog/res/values-ka/strings.xml new file mode 100644 index 000000000000..4c949c496785 --- /dev/null +++ b/packages/SimAppDialog/res/values-ka/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim აპის დიალოგი"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"გაააქტიურეთ მობილური სერვისი"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"ახალი SIM ბარათის გამართული მუშაობისთვის საჭიროა <xliff:g id="ID_1">%1$s</xliff:g> აპის ინსტალაცია"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"ახალი SIM ბარათის გამართული მუშაობისთვის საჭიროა ოპერატორის აპის ინსტალაცია"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ახლა არა"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"აპის ჩამოტვირთვა"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-kk/strings.xml b/packages/SimAppDialog/res/values-kk/strings.xml new file mode 100644 index 000000000000..d7bf9aebde8f --- /dev/null +++ b/packages/SimAppDialog/res/values-kk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Мобильдік қызметті іске қосыңыз"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Жаңа SIM картаңыз дұрыс жұмыс істеуі үшін, <xliff:g id="ID_1">%1$s</xliff:g> қолданбасын орнатуыңыз қажет."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Жаңа SIM картаңыз дұрыс жұмыс істеуі үшін, оператордың қолданбасын орнатуыңыз қажет."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Қазір емес"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Қолданбаны жүктеп алу"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-km/strings.xml b/packages/SimAppDialog/res/values-km/strings.xml new file mode 100644 index 000000000000..9962aa6c3545 --- /dev/null +++ b/packages/SimAppDialog/res/values-km/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"បើកដំណើរការសេវាកម្មឧបករណ៍ចល័ត"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"ដើម្បីធ្វើឱ្យស៊ីមថ្មីរបស់អ្នកដំណើរការបានត្រឹមត្រូវ អ្នកនឹងត្រូវដំឡើងកម្មវិធី <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"ដើម្បីធ្វើឱ្យស៊ីមថ្មីរបស់អ្នកដំណើរការបានត្រឹមត្រូវ អ្នកនឹងត្រូវដំឡើងកម្មវិធីក្រុមហ៊ុនសេវាទូរសព្ទ"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"កុំទាន់"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ទាញយកកម្មវិធី"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-kn/strings.xml b/packages/SimAppDialog/res/values-kn/strings.xml new file mode 100644 index 000000000000..c1c3b9ad5917 --- /dev/null +++ b/packages/SimAppDialog/res/values-kn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"ಸಿಮ್ ಆ್ಯಪ್ ಡೈಲಾಗ್"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"ಮೊಬೈಲ್ ಸೇವೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"ನಿಮ್ಮ ಹೊಸ ಸಿಮ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಹಾಗೆ ಮಾಡಲು, ನೀವು <xliff:g id="ID_1">%1$s</xliff:g> ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಬೇಕು"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"ನಿಮ್ಮ ಹೊಸ ಸಿಮ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಹಾಗೆ ಮಾಡಲು, ನೀವು ವಾಹಕ ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಬೇಕು"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ಈಗ ಬೇಡ"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ಆ್ಯಪ್ ಡೌನ್ಲೋಡ್ ಮಾಡಿ"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ko/strings.xml b/packages/SimAppDialog/res/values-ko/strings.xml new file mode 100644 index 000000000000..ebecc8023b6d --- /dev/null +++ b/packages/SimAppDialog/res/values-ko/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM 앱 대화상자"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"모바일 서비스 활성화"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"새로운 SIM을 정상적으로 사용하려면 <xliff:g id="ID_1">%1$s</xliff:g> 앱을 설치해야 합니다."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"새로운 SIM을 정상적으로 사용하려면 이동통신사 앱을 설치해야 합니다."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"나중에"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"앱 다운로드"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ky/strings.xml b/packages/SimAppDialog/res/values-ky/strings.xml new file mode 100644 index 000000000000..32db4210822a --- /dev/null +++ b/packages/SimAppDialog/res/values-ky/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM-картанын колдонмосунун диалогу"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Мобилдик кызматты жандыруу"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Жаңы SIM-картаңыз талаптагыдай иштеши үчүн, <xliff:g id="ID_1">%1$s</xliff:g> колдонмосун орнотуп алышыңыз керек"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Жаңы SIM картаңыз талаптагыдай иштеши үчүн, байланыш операторунун колдонмосун орнотуп алышыңыз керек"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Азыр эмес"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Колдонмону жүктөп алуу"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-lo/strings.xml b/packages/SimAppDialog/res/values-lo/strings.xml new file mode 100644 index 000000000000..97eab8684b70 --- /dev/null +++ b/packages/SimAppDialog/res/values-lo/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"ກ່ອງໂຕ້ຕອບແອັບຊິມ"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"ເປີດໃຊ້ບໍລິການມືຖື"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"ເພື່ອເຮັດໃຫ້ຊິມໃໝ່ຂອງທ່ານເຮັດວຽກໄດ້ຕາມປົກກະຕິ, ທ່ານຕ້ອງຕິດຕັ້ງແອັບ <xliff:g id="ID_1">%1$s</xliff:g> ກ່ອນ"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"ເພື່ອເຮັດໃຫ້ຊິມໃໝ່ຂອງທ່ານເຮັດວຽກໄດ້ຕາມປົກກະຕິ, ທ່ານຕ້ອງຕິດຕັ້ງແອັບຜູ້ໃຫ້ບໍລິການກ່ອນ"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ບໍ່ຟ້າວເທື່ອ"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ດາວໂຫຼດແອັບ"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-lt/strings.xml b/packages/SimAppDialog/res/values-lt/strings.xml new file mode 100644 index 000000000000..ab0edbb9951a --- /dev/null +++ b/packages/SimAppDialog/res/values-lt/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM kortelės dialogo langas"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Įjungti mob. ryšio paslaugą"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Norint, kad naujoji SIM kortelė tinkamai veiktų, reikia įdiegti „<xliff:g id="ID_1">%1$s</xliff:g>“ programą"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Norint, kad naujoji SIM kortelė tinkamai veiktų, reikia įdiegti operatoriaus programą"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ne dabar"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Atsisiųsti programą"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-lv/strings.xml b/packages/SimAppDialog/res/values-lv/strings.xml new file mode 100644 index 000000000000..17cb414f32a5 --- /dev/null +++ b/packages/SimAppDialog/res/values-lv/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"SIM kartes lietotnes dialoglodziņš"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivizējiet mobilo pakalpojumu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Lai jaunā SIM karte darbotos pareizi, jums būs jāinstalē lietotne <xliff:g id="ID_1">%1$s</xliff:g>."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Lai jaunā SIM karte darbotos pareizi, jums būs jāinstalē mobilo sakaru operatora lietotne."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Vēlāk"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Lejupielādēt lietotni"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-mk/strings.xml b/packages/SimAppDialog/res/values-mk/strings.xml new file mode 100644 index 000000000000..481dfaeea7f8 --- /dev/null +++ b/packages/SimAppDialog/res/values-mk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Активирајте мобилна услуга"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"За да работи правилно вашата нова SIM-картичка, треба да ја инсталирате апликацијата <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"За да работи правилно вашата нова SIM-картичка, треба да ја инсталирате апликацијата на операторот"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Не сега"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Преземете апликација"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ml/strings.xml b/packages/SimAppDialog/res/values-ml/strings.xml new file mode 100644 index 000000000000..8e0b4656c8fc --- /dev/null +++ b/packages/SimAppDialog/res/values-ml/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"സിം ആപ്പ് ഡയലോഗ്"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"മൊബൈൽ സേവനം സജീവമാക്കുക"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"നിങ്ങളുടെ പുതിയ സിം ശരിയായി പ്രവർത്തിക്കുന്നതിന് <xliff:g id="ID_1">%1$s</xliff:g> ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യേണ്ടതുണ്ട്"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"നിങ്ങളുടെ പുതിയ സിം ശരിയായി പ്രവർത്തിക്കുന്നതിന് കാരിയർ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യേണ്ടതുണ്ട്"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ഇപ്പോൾ വേണ്ട"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ആപ്പ് ഡൗൺലോഡ് ചെയ്യുക"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-mn/strings.xml b/packages/SimAppDialog/res/values-mn/strings.xml new file mode 100644 index 000000000000..f21b80bc759b --- /dev/null +++ b/packages/SimAppDialog/res/values-mn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim аппын харилцах цонх"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Мобайл үйлчилгээг идэвхжүүлэх"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Та шинэ СИМ-ээ зөв ажиллуулахын тулд <xliff:g id="ID_1">%1$s</xliff:g> аппыг суулгах хэрэгтэй болно"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Та шинэ СИМ-ээ зөв ажиллуулахын тулд оператор компанийхаа аппыг суулгах хэрэгтэй болно"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Одоо биш"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Апп татах"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-mr/strings.xml b/packages/SimAppDialog/res/values-mr/strings.xml new file mode 100644 index 000000000000..936abe98eb5c --- /dev/null +++ b/packages/SimAppDialog/res/values-mr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"मोबाइल सेवा अॅक्टिव्हेट करा"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"तुमच्या नवीन सिम ने योग्यरीत्या काम करावे यासाठी तुम्हाला <xliff:g id="ID_1">%1$s</xliff:g> ॲप इंस्टॉल करणे आवश्यक आहे"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"तुमच्या नवीन सिम ने योग्यरीत्या काम करावे यासाठी तुम्हाला वाहकाचे ॲप इंस्टॉल करणे आवश्यक आहे"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"आता नको"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"अॅप डाउनलोड करा"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ms/strings.xml b/packages/SimAppDialog/res/values-ms/strings.xml new file mode 100644 index 000000000000..2d9722b278ff --- /dev/null +++ b/packages/SimAppDialog/res/values-ms/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Dialog Apl Sim"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktifkan perkhdmtn mudah alih"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Untuk memastikan SIM baharu anda berfungsi dengan betul, anda perlu memasang apl <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Untuk memastikan SIM baharu anda berfungsi dengan betul, anda perlu memasang apl pembawa"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Bukan sekarang"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Muat turun apl"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-my/strings.xml b/packages/SimAppDialog/res/values-my/strings.xml new file mode 100644 index 000000000000..55499e32f30d --- /dev/null +++ b/packages/SimAppDialog/res/values-my/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"ဆင်းမ်အက်ပ် အကွက်"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"မိုဘိုင်းဝန်ဆောင်မှု စဖွင့်ရန်"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"သင့်ဆင်းမ်ကတ်အသစ်ကို ကောင်းမွန်စွာ အသုံးပြုနိုင်ရန် <xliff:g id="ID_1">%1$s</xliff:g> အက်ပ်ကို ထည့်သွင်းရပါမည်"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"သင့်ဆင်းမ်ကတ်အသစ်ကို ကောင်းမွန်စွာ အသုံးပြုနိုင်ရန် ဝန်ဆောင်မှုပေးသူအက်ပ်ကို ထည့်သွင်းရပါမည်"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ယခုမလုပ်ပါ"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"အက်ပ် ဒေါင်းလုဒ်လုပ်ရန်"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-nb/strings.xml b/packages/SimAppDialog/res/values-nb/strings.xml new file mode 100644 index 000000000000..873830fbe52a --- /dev/null +++ b/packages/SimAppDialog/res/values-nb/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Dialogboks for SIM-kortapp"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktiver mobiltjeneste"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"For å få det nye SIM-kortet ditt til å fungere som det skal, må du installere <xliff:g id="ID_1">%1$s</xliff:g>-appen"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"For å få det nye SIM-kortet ditt til å fungere som det skal, må du installere operatørappen"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ikke nå"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Last ned appen"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ne/strings.xml b/packages/SimAppDialog/res/values-ne/strings.xml new file mode 100644 index 000000000000..ee69e4c1189d --- /dev/null +++ b/packages/SimAppDialog/res/values-ne/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"सिम एपको डायलग"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"मोबाइल सेवा सक्रिय गर्नुहोस्"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"तपाईंको नयाँ SIM ले राम्रोसँग काम गर्न तपाईंले <xliff:g id="ID_1">%1$s</xliff:g> एप इन्स्टल गर्नु पर्ने हुन्छ"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"तपाईंको नयाँ SIM ले राम्रोसँग काम गर्न तपाईंले आफ्नो सेवा प्रदायकको एप इन्स्टल गर्नु पर्ने हुन्छ"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"अहिले होइन"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"एप डाउनलोड गर्नुहोस्"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-nl/strings.xml b/packages/SimAppDialog/res/values-nl/strings.xml new file mode 100644 index 000000000000..9a1ab226952c --- /dev/null +++ b/packages/SimAppDialog/res/values-nl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Mobiele service activeren"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Als je je nieuwe simkaart wilt gaan gebruiken, moet je de <xliff:g id="ID_1">%1$s</xliff:g>-app installeren"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Als je je nieuwe simkaart wilt gaan gebruiken, moet je de app van je provider installeren"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Niet nu"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"App downloaden"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-or/strings.xml b/packages/SimAppDialog/res/values-or/strings.xml new file mode 100644 index 000000000000..9a7906589401 --- /dev/null +++ b/packages/SimAppDialog/res/values-or/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"ମୋବାଇଲ୍ ସେବା ସକ୍ରିୟ କରନ୍ତୁ"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"ଆପଣଙ୍କ ନୂଆ SIM କାର୍ଡ ଠିକ୍ ଭାବେ କାମ କରିବା ପାଇଁ, ଆପଣଙ୍କୁ <xliff:g id="ID_1">%1$s</xliff:g> ଆପ୍ ଇନଷ୍ଟଲ୍ କରିବାକୁ ହେବ"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"ଆପଣଙ୍କ ନୂଆ SIM କାର୍ଡ ଠିକ୍ ଭାବେ କାମ କରିବା ପାଇଁ, ଆପଣଙ୍କୁ ମୋବାଇଲ୍ କମ୍ପାନୀ ଆପ୍ ଇନଷ୍ଟଲ୍ କରିବାକୁ ହେବ"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ଏବେ ନୁହେଁ"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ଆପ୍ ଡାଉନଲୋଡ୍ କରନ୍ତୁ"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-pa/strings.xml b/packages/SimAppDialog/res/values-pa/strings.xml new file mode 100644 index 000000000000..04be7a5ee3e2 --- /dev/null +++ b/packages/SimAppDialog/res/values-pa/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"ਮੋਬਾਈਲ ਸੇਵਾ ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"ਤੁਹਾਡੀ ਨਵੀਂ ਸਿਮ ਦੇ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ <xliff:g id="ID_1">%1$s</xliff:g> ਐਪ ਸਥਾਪਤ ਕਰਨ ਦੀ ਲੋੜ ਪਵੇਗੀ"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"ਤੁਹਾਡੀ ਨਵੀਂ ਸਿਮ ਦੇ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਕੈਰੀਅਰ ਐਪ ਸਥਾਪਤ ਕਰਨ ਦੀ ਲੋੜ ਪਵੇਗੀ"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ਹਾਲੇ ਨਹੀਂ"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ਐਪ ਡਾਊਨਲੋਡ ਕਰੋ"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-pl/strings.xml b/packages/SimAppDialog/res/values-pl/strings.xml new file mode 100644 index 000000000000..fcd765a0e663 --- /dev/null +++ b/packages/SimAppDialog/res/values-pl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Okno aplikacji do obsługi karty SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktywuj usługę sieci"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Aby nowa karta SIM działała prawidłowo, musisz zainstalować aplikację <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Aby nowa karta SIM działała prawidłowo, musisz zainstalować aplikację operatora"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Nie teraz"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Pobierz aplikację"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-pt-rBR/strings.xml b/packages/SimAppDialog/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000000..abf8dbd27ecc --- /dev/null +++ b/packages/SimAppDialog/res/values-pt-rBR/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Caixa de diálogo do app do chip"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Ativar serviço móvel"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Para que o novo chip funcione corretamente, instale o app <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para que o novo chip funcione corretamente, instale o app da operadora"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Agora não"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Fazer o download do app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-pt-rPT/strings.xml b/packages/SimAppDialog/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000000..788ab8d8322f --- /dev/null +++ b/packages/SimAppDialog/res/values-pt-rPT/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Caixa de diálogo da app do SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Ative o serviço móvel"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Para que o novo SIM funcione corretamente, terá de instalar a app <xliff:g id="ID_1">%1$s</xliff:g>."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para que o novo SIM funcione corretamente, terá de instalar a app do operador."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Agora não"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Transferir app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-pt/strings.xml b/packages/SimAppDialog/res/values-pt/strings.xml new file mode 100644 index 000000000000..abf8dbd27ecc --- /dev/null +++ b/packages/SimAppDialog/res/values-pt/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Caixa de diálogo do app do chip"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Ativar serviço móvel"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Para que o novo chip funcione corretamente, instale o app <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para que o novo chip funcione corretamente, instale o app da operadora"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Agora não"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Fazer o download do app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ro/strings.xml b/packages/SimAppDialog/res/values-ro/strings.xml new file mode 100644 index 000000000000..21663d125f7f --- /dev/null +++ b/packages/SimAppDialog/res/values-ro/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Activați serviciul mobil"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Pentru ca noul card SIM să funcționeze corect, va trebui să instalați aplicația <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Pentru ca noul card SIM să funcționeze corect, va trebui să instalați aplicația operatorului"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Nu acum"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Descărcați aplicația"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ru/strings.xml b/packages/SimAppDialog/res/values-ru/strings.xml new file mode 100644 index 000000000000..7a32a7a871f8 --- /dev/null +++ b/packages/SimAppDialog/res/values-ru/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Приложение для SIM-карты"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Активируйте мобильную связь"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Чтобы новая SIM-карта работала корректно, установите приложение оператора \"<xliff:g id="ID_1">%1$s</xliff:g>\"."</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Чтобы новая SIM-карта работала корректно, установите приложение оператора связи."</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Позже"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Скачать приложение"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-si/strings.xml b/packages/SimAppDialog/res/values-si/strings.xml new file mode 100644 index 000000000000..a4be55fda940 --- /dev/null +++ b/packages/SimAppDialog/res/values-si/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"ජංගම සේවාව සක්රිය කරන්න"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"ඔබේ නව SIM නිසි ලෙස වැඩ කිරීමට, ඔබට <xliff:g id="ID_1">%1$s</xliff:g> යෙදුම ස්ථාපනය කිරීමට අවශ්ය වනු ඇත"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"ඔබේ නව SIM නිසි ලෙස වැඩ කිරීමට, ඔබට වාහක යෙදුම ස්ථාපනය කිරීමට අවශ්ය වනු ඇත"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"දැන් නොවේ"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"යෙදුම බාගන්න"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-sk/strings.xml b/packages/SimAppDialog/res/values-sk/strings.xml new file mode 100644 index 000000000000..bafb6ddfabde --- /dev/null +++ b/packages/SimAppDialog/res/values-sk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Dialógové okno aplikácie SIM karty"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivujte mobilnú službu"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Musíte nainštalovať aplikáciu <xliff:g id="ID_1">%1$s</xliff:g>, aby nová SIM karta fungovala správne"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Musíte nainštalovať aplikáciu operátora, aby nová SIM karta fungovala správne"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Teraz nie"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Stiahnuť aplikáciu"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-sl/strings.xml b/packages/SimAppDialog/res/values-sl/strings.xml new file mode 100644 index 000000000000..4a8659a4c922 --- /dev/null +++ b/packages/SimAppDialog/res/values-sl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Pogovorno okno aplikacije za SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivirajte mobilno storitev"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Če želite, da bo nova kartica SIM pravilno delovala, morate namestiti aplikac. operaterja <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Če želite, da bo nova kartica SIM pravilno delovala, morate namestiti aplikacijo operaterja"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ne zdaj"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Prenos aplikacije"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-sq/strings.xml b/packages/SimAppDialog/res/values-sq/strings.xml new file mode 100644 index 000000000000..4ba1b8a4d180 --- /dev/null +++ b/packages/SimAppDialog/res/values-sq/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Dialogu i aplikacionit të kartës SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivizo shërbimin celular"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Që karta e re SIM të funksionojë siç duhet, duhet të instalosh aplikacionin <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Që karta e re SIM të funksionojë siç duhet, duhet të instalosh aplikacionin e operatorit celular"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Jo tani"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Shkarko aplikacionin"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-sr/strings.xml b/packages/SimAppDialog/res/values-sr/strings.xml new file mode 100644 index 000000000000..5d5921e4d48d --- /dev/null +++ b/packages/SimAppDialog/res/values-sr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Активирајте мобилну услугу"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Да би нова SIM картица исправно радила, треба да инсталирате апликацију <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Да би нова SIM картица исправно радила, треба да инсталирате апликацију мобилног оператера"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Не сада"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Преузми апликацију"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-sv/strings.xml b/packages/SimAppDialog/res/values-sv/strings.xml new file mode 100644 index 000000000000..1da5de1dfbae --- /dev/null +++ b/packages/SimAppDialog/res/values-sv/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivera mobiltjänst"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Du måste installera <xliff:g id="ID_1">%1$s</xliff:g>-appen om ditt nya SIM-kort ska fungera ordentligt"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Du måste installera operatörens app om ditt nya SIM-kort ska fungera ordentligt"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Inte nu"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Ladda ned app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-sw/strings.xml b/packages/SimAppDialog/res/values-sw/strings.xml new file mode 100644 index 000000000000..b897927f5d6c --- /dev/null +++ b/packages/SimAppDialog/res/values-sw/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Kidirisha cha Programu ya SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Washa huduma ya simu za mkononi"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Ili SIM yako mpya ifanye kazi vizuri, utahitajika kusakinisha programu ya <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Ili SIM yako mpya ifanye kazi vizuri, utahitajika kusakinisha programu ya mtoa huduma"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Si sasa"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Pakua programu"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-te/strings.xml b/packages/SimAppDialog/res/values-te/strings.xml new file mode 100644 index 000000000000..8a05fe4ee47d --- /dev/null +++ b/packages/SimAppDialog/res/values-te/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"సిమ్ యాప్ డైలాగ్"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"మొబైల్ సేవను యాక్టివేట్ చేయండి"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"మీ SIM సరిగ్గా పనిచేయడానికి, మీరు <xliff:g id="ID_1">%1$s</xliff:g> యాప్ను ఇన్స్టాల్ చేయాల్సి ఉంటుంది"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"మీ SIM సరిగ్గా పనిచేయడానికి, మీరు క్యారియర్ యాప్ని ఇన్స్టాల్ చేయాల్సి ఉంటుంది"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ఇప్పుడు కాదు"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"యాప్ని డౌన్లోడ్ చేయండి"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-th/strings.xml b/packages/SimAppDialog/res/values-th/strings.xml new file mode 100644 index 000000000000..00b7258bfd61 --- /dev/null +++ b/packages/SimAppDialog/res/values-th/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"เปิดใช้งานบริการมือถือ"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"คุณจะต้องติดตั้งแอป <xliff:g id="ID_1">%1$s</xliff:g> เพื่อให้ซิมใหม่ทำงานได้อย่างถูกต้อง"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"คุณจะต้องติดตั้งแอปของผู้ให้บริการเพื่อให้ซิมใหม่ทำงานได้อย่างถูกต้อง"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ไว้ทีหลัง"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ดาวน์โหลดแอป"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-tl/strings.xml b/packages/SimAppDialog/res/values-tl/strings.xml new file mode 100644 index 000000000000..f6c304fbce25 --- /dev/null +++ b/packages/SimAppDialog/res/values-tl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"I-activate ang mobile service"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Para mapagana nang maayos ang iyong bagong SIM, kakailanganin mong i-install ang <xliff:g id="ID_1">%1$s</xliff:g> app"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para mapagana nang maayos ang iyong bagong SIM, kakailanganin mong i-install ang app ng carrier"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Huwag ngayon"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"I-download ang app"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-tr/strings.xml b/packages/SimAppDialog/res/values-tr/strings.xml new file mode 100644 index 000000000000..c33fa27910be --- /dev/null +++ b/packages/SimAppDialog/res/values-tr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Mobil hizmeti etkinleştirin"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Yeni SIM\'inizin düzgün çalışması için <xliff:g id="ID_1">%1$s</xliff:g> uygulamasını yüklemeniz gerekir"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Yeni SIM\'inizin düzgün çalışması için operatör uygulamasını yüklemeniz gerekir"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Şimdi değil"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Uygulama indir"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-uk/strings.xml b/packages/SimAppDialog/res/values-uk/strings.xml new file mode 100644 index 000000000000..e86f49eaa99f --- /dev/null +++ b/packages/SimAppDialog/res/values-uk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Активувати мобільний сервіс"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Установіть додаток <xliff:g id="ID_1">%1$s</xliff:g>, щоб нова SIM-карта працювала належним чином"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Установіть додаток оператора, щоб нова SIM-карта працювала належним чином"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Не зараз"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Завантажити додаток"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-ur/strings.xml b/packages/SimAppDialog/res/values-ur/strings.xml new file mode 100644 index 000000000000..1e071d8bbe48 --- /dev/null +++ b/packages/SimAppDialog/res/values-ur/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim ایپ ڈائیلاگ"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"موبائل سروس فعال کریں"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"آپ کی نئی SIM کو ٹھیک طرح سے کام کرنے کے لیے آپ کو <xliff:g id="ID_1">%1$s</xliff:g> ایپ انسٹال کرنے کی ضرورت ہو گی"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"آپ کی نئی SIM کو ٹھیک طرح سے کام کرنے کے لیے آپ کو کیریئر ایپ انسٹال کرنے کی ضرورت ہو گی"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"ابھی نہیں"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"ایپ ڈاؤن لوڈ کریں"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-uz/strings.xml b/packages/SimAppDialog/res/values-uz/strings.xml new file mode 100644 index 000000000000..49a54a2d59ca --- /dev/null +++ b/packages/SimAppDialog/res/values-uz/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Mobil xizmatni faollashtirish"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Yangi SIM karta bexato ishlashi uchun <xliff:g id="ID_1">%1$s</xliff:g> ilovasini oʻrnatishingiz lozim"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Yangi SIM karta bexato ishlashi uchun aloqa operatori ilovasini oʻrnatishingiz lozim"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Keyinroq"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Ilovani yuklab olish"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-vi/strings.xml b/packages/SimAppDialog/res/values-vi/strings.xml new file mode 100644 index 000000000000..6ff3c3bc4ef7 --- /dev/null +++ b/packages/SimAppDialog/res/values-vi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Hộp thoại ứng dụng SIM"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Kích hoạt dịch vụ di động"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Để SIM mới hoạt động đúng cách, bạn cần phải cài đặt ứng dụng <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Để SIM mới hoạt động đúng cách, bạn cần phải cài đặt ứng dụng của nhà mạng"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Để sau"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Tải ứng dụng xuống"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-zh-rCN/strings.xml b/packages/SimAppDialog/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000000..4b3fc5f976f4 --- /dev/null +++ b/packages/SimAppDialog/res/values-zh-rCN/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"激活移动网络服务"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"您需要安装<xliff:g id="ID_1">%1$s</xliff:g>应用,新 SIM 卡才能正常运行"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"您需要安装运营商应用,新 SIM 卡才能正常运行"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"以后再说"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"下载应用"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-zh-rHK/strings.xml b/packages/SimAppDialog/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000000..bc490f0b10b3 --- /dev/null +++ b/packages/SimAppDialog/res/values-zh-rHK/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"啟動流動服務"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"為確保新的 SIM 卡正常運作,您必須先安裝「<xliff:g id="ID_1">%1$s</xliff:g>」應用程式"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"為確保新的 SIM 卡正常運作,您必須先安裝流動網絡供應商應用程式"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"暫時不要"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"下載應用程式"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-zh-rTW/strings.xml b/packages/SimAppDialog/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000000..14ec10f0a91c --- /dev/null +++ b/packages/SimAppDialog/res/values-zh-rTW/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"啟用行動服務"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"你必須安裝「<xliff:g id="ID_1">%1$s</xliff:g>」應用程式,新的 SIM 卡才能正常運作"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"你必須安裝電信業者應用程式,新的 SIM 卡才能正常運作"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"暫時不要"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"下載應用程式"</string> +</resources> diff --git a/packages/SimAppDialog/res/values-zu/strings.xml b/packages/SimAppDialog/res/values-zu/strings.xml new file mode 100644 index 000000000000..cf3b935d24f4 --- /dev/null +++ b/packages/SimAppDialog/res/values-zu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name" msgid="8898068901680117589">"Ibhokisi Lohlelo Lokusebenza le-Sim"</string> + <string name="install_carrier_app_title" msgid="334729104862562585">"Yenza kusebenze isevisi yeselula"</string> + <string name="install_carrier_app_description" msgid="4014303558674923797">"Ukuze i-SIM yakho entsha isebenze kahle, kuzodingeka ufake uhlelo lokusebenza le-<xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Ukuze i-SIM yakho entsha isebenze kahle, kuzodingeka ufake uhlelo lokusebenza lenkampini yenethiwekhi"</string> + <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Hhayi manje"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Landa uhlelo lokusebenza"</string> +</resources> diff --git a/packages/SoundPicker/res/values-af/strings.xml b/packages/SoundPicker/res/values-af/strings.xml index cf6414659f6e..10110f6bf351 100644 --- a/packages/SoundPicker/res/values-af/strings.xml +++ b/packages/SoundPicker/res/values-af/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Verstekluitoon"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Verstekkennisgewingklank"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Verstekwekkerklank"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Voeg luitoon by"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Voeg wekker by"</string> diff --git a/packages/SoundPicker/res/values-am/strings.xml b/packages/SoundPicker/res/values-am/strings.xml index 9026d3629180..57f789792547 100644 --- a/packages/SoundPicker/res/values-am/strings.xml +++ b/packages/SoundPicker/res/values-am/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ነባሪ የስልክ ላይ ጥሪ"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ነባሪ የማሳወቂያ ድምጽ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ነባሪ የማንቂያ ድምፅ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"የጥሪ ቅላጼ አክል"</string> <string name="add_alarm_text" msgid="3545497316166999225">"የማንቂያ ደውል አክል"</string> diff --git a/packages/SoundPicker/res/values-ar/strings.xml b/packages/SoundPicker/res/values-ar/strings.xml index 0af7ff52a928..57740ef69a70 100644 --- a/packages/SoundPicker/res/values-ar/strings.xml +++ b/packages/SoundPicker/res/values-ar/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"نغمة الرنين التلقائية"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"الصوت التلقائي للإشعارات"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"الصوت التلقائي للمنبّه"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"إضافة نغمة رنين"</string> <string name="add_alarm_text" msgid="3545497316166999225">"إضافة منبه"</string> diff --git a/packages/SoundPicker/res/values-as/strings.xml b/packages/SoundPicker/res/values-as/strings.xml index 6cbea0797696..659f2d5f7e16 100644 --- a/packages/SoundPicker/res/values-as/strings.xml +++ b/packages/SoundPicker/res/values-as/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"পূর্বনিধার্ৰিত ৰিংট\'ন"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"জাননীৰ ডিফ’ল্ট ধ্বনি"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"এলাৰ্মৰ ডিফ\'ল্ট ধ্বনি"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ৰিংট\'ন যোগ কৰক"</string> <string name="add_alarm_text" msgid="3545497316166999225">"এলাৰ্ম যোগ কৰক"</string> diff --git a/packages/SoundPicker/res/values-az/strings.xml b/packages/SoundPicker/res/values-az/strings.xml index 16f739d32346..93f4d7981a0a 100644 --- a/packages/SoundPicker/res/values-az/strings.xml +++ b/packages/SoundPicker/res/values-az/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Defolt rinqton"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Defolt bildiriş səsi"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Defolt siqnal səsi"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Zəng səsi daxil edin"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Siqnal əlavə edin"</string> diff --git a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml index 03fd58a4cd69..ba8e87fe0a67 100644 --- a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml +++ b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Podrazumevani zvuk zvona"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Podrazumevani zvuk obaveštenja"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Podrazumevani zvuk alarma"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Dodaj melodiju zvona"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Dodajte alarm"</string> diff --git a/packages/SoundPicker/res/values-be/strings.xml b/packages/SoundPicker/res/values-be/strings.xml index 55f6ab3e875e..81b99877def6 100644 --- a/packages/SoundPicker/res/values-be/strings.xml +++ b/packages/SoundPicker/res/values-be/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Стандартны рынгтон"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Стандартны гук апавяшчэння"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Стандартны сігнал будзільніка"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Дадаць рынгтон"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Дадаць будзільнік"</string> diff --git a/packages/SoundPicker/res/values-bg/strings.xml b/packages/SoundPicker/res/values-bg/strings.xml index c31f35f9e4d4..e1cd2a697bf0 100644 --- a/packages/SoundPicker/res/values-bg/strings.xml +++ b/packages/SoundPicker/res/values-bg/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Стандартна мелодия"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Стандартен звук за известяване"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Стандартен звук за будилника"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Добавяне на мелодия"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Добавяне на будилник"</string> diff --git a/packages/SoundPicker/res/values-bn/strings.xml b/packages/SoundPicker/res/values-bn/strings.xml index ebbed152833d..e248c2c59411 100644 --- a/packages/SoundPicker/res/values-bn/strings.xml +++ b/packages/SoundPicker/res/values-bn/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ডিফল্ট রিংটোন"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ডিফল্ট বিজ্ঞপ্তির সাউন্ড"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ডিফল্ট অ্যালার্মের সাউন্ড"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"রিংটোন যোগ করুন"</string> <string name="add_alarm_text" msgid="3545497316166999225">"অ্যালার্ম যোগ করুন"</string> diff --git a/packages/SoundPicker/res/values-bs/strings.xml b/packages/SoundPicker/res/values-bs/strings.xml index ad4fe573090d..fdabd5dd22c7 100644 --- a/packages/SoundPicker/res/values-bs/strings.xml +++ b/packages/SoundPicker/res/values-bs/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Zadana melodija zvona"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Zadani zvuk obavještenja"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Zadani zvuk alarma"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Dodaj melodiju zvona"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Dodajte alarm"</string> diff --git a/packages/SoundPicker/res/values-ca/strings.xml b/packages/SoundPicker/res/values-ca/strings.xml index 5b324292c485..9170740af018 100644 --- a/packages/SoundPicker/res/values-ca/strings.xml +++ b/packages/SoundPicker/res/values-ca/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"So predeterminat"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"So de notificació predeterminat"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"So d\'alarma predeterminat"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Afegeix un so de trucada"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Afegeix una alarma"</string> diff --git a/packages/SoundPicker/res/values-cs/strings.xml b/packages/SoundPicker/res/values-cs/strings.xml index d60e217508c0..899277eb1f93 100644 --- a/packages/SoundPicker/res/values-cs/strings.xml +++ b/packages/SoundPicker/res/values-cs/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Výchozí vyzváněcí tón"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Výchozí zvuk oznámení"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Výchozí zvuk budíku"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Přidat vyzváněcí tón"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Přidat budík"</string> diff --git a/packages/SoundPicker/res/values-da/strings.xml b/packages/SoundPicker/res/values-da/strings.xml index c4ba8ee7b6dd..fb3b1645b44d 100644 --- a/packages/SoundPicker/res/values-da/strings.xml +++ b/packages/SoundPicker/res/values-da/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Standardringetone"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Standardlyd for notifikationer"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Standardlyd for alarmer"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Tilføj ringetone"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Tilføj alarm"</string> diff --git a/packages/SoundPicker/res/values-de/strings.xml b/packages/SoundPicker/res/values-de/strings.xml index ca7e498934ff..b707874d8aa0 100644 --- a/packages/SoundPicker/res/values-de/strings.xml +++ b/packages/SoundPicker/res/values-de/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Standard-Klingelton"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Standard-Benachrichtigungston"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Standard-Weckton"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Klingelton hinzufügen"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Weckruf hinzufügen"</string> diff --git a/packages/SoundPicker/res/values-el/strings.xml b/packages/SoundPicker/res/values-el/strings.xml index b600e8801026..05c69fed8c86 100644 --- a/packages/SoundPicker/res/values-el/strings.xml +++ b/packages/SoundPicker/res/values-el/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Προεπιλεγμένος ήχος κλήσης"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Προεπιλεγμένος ήχος ειδοποίησης"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Προεπιλεγμένος ήχος ειδοποίησης"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Προσθήκη ήχου κλήσης"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Προσθήκη ξυπνητηριού"</string> diff --git a/packages/SoundPicker/res/values-es-rUS/strings.xml b/packages/SoundPicker/res/values-es-rUS/strings.xml index e6cb5ff1c423..96c5e847b1c3 100644 --- a/packages/SoundPicker/res/values-es-rUS/strings.xml +++ b/packages/SoundPicker/res/values-es-rUS/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Tono predeterminado"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Sonido de notificación predeterminado"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Sonido de alarma predeterminado"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Agregar tono"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Agregar alarma"</string> diff --git a/packages/SoundPicker/res/values-es/strings.xml b/packages/SoundPicker/res/values-es/strings.xml index c7e8be2000d6..feccaefb2b8c 100644 --- a/packages/SoundPicker/res/values-es/strings.xml +++ b/packages/SoundPicker/res/values-es/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Tono por defecto"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Sonido de notificación predeterminado"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Sonido de alarma predeterminado"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Añadir tono de llamada"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Añadir alarma"</string> diff --git a/packages/SoundPicker/res/values-eu/strings.xml b/packages/SoundPicker/res/values-eu/strings.xml index 33133b03943c..ae3fb99d324c 100644 --- a/packages/SoundPicker/res/values-eu/strings.xml +++ b/packages/SoundPicker/res/values-eu/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Tonu lehenetsia"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Jakinarazpenen soinu lehenetsia"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Alarmaren soinu lehenetsia"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Gehitu tonua"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Gehitu alarma"</string> diff --git a/packages/SoundPicker/res/values-fa/strings.xml b/packages/SoundPicker/res/values-fa/strings.xml index 908efaf675c2..bc39f74cc42b 100644 --- a/packages/SoundPicker/res/values-fa/strings.xml +++ b/packages/SoundPicker/res/values-fa/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"آهنگ زنگ پیشفرض"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"صدای اعلان پیشفرض"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"صدای زنگ پیشفرض"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"افزودن آهنگ زنگ"</string> <string name="add_alarm_text" msgid="3545497316166999225">"افزودن زنگ"</string> diff --git a/packages/SoundPicker/res/values-fi/strings.xml b/packages/SoundPicker/res/values-fi/strings.xml index 812e0ecb249e..2d602639510b 100644 --- a/packages/SoundPicker/res/values-fi/strings.xml +++ b/packages/SoundPicker/res/values-fi/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Oletussoittoääni"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Ilmoituksen oletusääni"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Herätyksen oletusääni"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Lisää soittoääni"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Lisää hälytys"</string> diff --git a/packages/SoundPicker/res/values-fr/strings.xml b/packages/SoundPicker/res/values-fr/strings.xml index ece6a137dac9..63182df7992f 100644 --- a/packages/SoundPicker/res/values-fr/strings.xml +++ b/packages/SoundPicker/res/values-fr/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Sonnerie par défaut"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Son de notification par défaut"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Son de l\'alarme par défaut"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Ajouter une sonnerie"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Ajouter une alarme"</string> diff --git a/packages/SoundPicker/res/values-gl/strings.xml b/packages/SoundPicker/res/values-gl/strings.xml index 2d75f224106f..70194c778216 100644 --- a/packages/SoundPicker/res/values-gl/strings.xml +++ b/packages/SoundPicker/res/values-gl/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Ton de chamada predeterminado"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Son de notificación predeterminado"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Son de alarma predeterminado"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Engadir ton de chamada"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Engadir alarma"</string> diff --git a/packages/SoundPicker/res/values-gu/strings.xml b/packages/SoundPicker/res/values-gu/strings.xml index 0505b46351f2..70d5c2c651b8 100644 --- a/packages/SoundPicker/res/values-gu/strings.xml +++ b/packages/SoundPicker/res/values-gu/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ડિફોલ્ટ રિંગટોન"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ડિફૉલ્ટ નોટિફિકેશન સાઉન્ડ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ડિફૉલ્ટ એલાર્મ સાઉન્ડ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"રિંગટોન ઉમેરો"</string> <string name="add_alarm_text" msgid="3545497316166999225">"અલાર્મ ઉમેરો"</string> diff --git a/packages/SoundPicker/res/values-hi/strings.xml b/packages/SoundPicker/res/values-hi/strings.xml index 1d18da21d778..316447c67ab4 100644 --- a/packages/SoundPicker/res/values-hi/strings.xml +++ b/packages/SoundPicker/res/values-hi/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"डिफ़ॉल्ट रिंगटोन"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"सूचना की डिफ़ॉल्ट आवाज़"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"डिफ़ॉल्ट अलार्म आवाज़"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"रिंगटोन जोड़ेंं"</string> <string name="add_alarm_text" msgid="3545497316166999225">"अलार्म जोड़ें"</string> diff --git a/packages/SoundPicker/res/values-hr/strings.xml b/packages/SoundPicker/res/values-hr/strings.xml index 1a398175a85e..ed0a27da735d 100644 --- a/packages/SoundPicker/res/values-hr/strings.xml +++ b/packages/SoundPicker/res/values-hr/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Zadana melodija zvona"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Zadani zvuk obavijesti"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Zadani zvuk alarma"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Dodaj melodiju zvona"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Dodaj alarm"</string> diff --git a/packages/SoundPicker/res/values-hu/strings.xml b/packages/SoundPicker/res/values-hu/strings.xml index 6b83509d5058..da0b1c452d2e 100644 --- a/packages/SoundPicker/res/values-hu/strings.xml +++ b/packages/SoundPicker/res/values-hu/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Alapértelmezett csengőhang"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Alapértelmezett értesítőhang"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Alapértelmezett ébresztési hang"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Csengőhang hozzáadása"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Ébresztés hozzáadása"</string> diff --git a/packages/SoundPicker/res/values-is/strings.xml b/packages/SoundPicker/res/values-is/strings.xml index 68994aa2b2d9..ee4ca2e46d98 100644 --- a/packages/SoundPicker/res/values-is/strings.xml +++ b/packages/SoundPicker/res/values-is/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Sjálfgefinn hringitónn"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Sjálfgefið hljóð tilkynninga"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Sjálfgefið hljóð í vekjara"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Bæta hringitóni við"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Bæta vekjara við"</string> diff --git a/packages/SoundPicker/res/values-it/strings.xml b/packages/SoundPicker/res/values-it/strings.xml index e9302c1b5b2e..f3fa56938465 100644 --- a/packages/SoundPicker/res/values-it/strings.xml +++ b/packages/SoundPicker/res/values-it/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Suoneria predefinita"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Suono di notifica predefinito"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Suono sveglia predefinito"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Aggiungi suoneria"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Aggiungi sveglia"</string> diff --git a/packages/SoundPicker/res/values-iw/strings.xml b/packages/SoundPicker/res/values-iw/strings.xml index 2bed8e05aac5..efe6f1e9e7e4 100644 --- a/packages/SoundPicker/res/values-iw/strings.xml +++ b/packages/SoundPicker/res/values-iw/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"רינגטון ברירת מחדל"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"צליל ברירת מחדל להתראות"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"צליל לשעון מעורר"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"רינגטון חדש"</string> <string name="add_alarm_text" msgid="3545497316166999225">"הוספת התראה"</string> diff --git a/packages/SoundPicker/res/values-ja/strings.xml b/packages/SoundPicker/res/values-ja/strings.xml index d3ebcccc3eb5..22f4e50879bf 100644 --- a/packages/SoundPicker/res/values-ja/strings.xml +++ b/packages/SoundPicker/res/values-ja/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"プリセット着信音"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"デフォルトの通知音"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"デフォルトの警告音"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"着信音を追加"</string> <string name="add_alarm_text" msgid="3545497316166999225">"アラームの追加"</string> diff --git a/packages/SoundPicker/res/values-ka/strings.xml b/packages/SoundPicker/res/values-ka/strings.xml index c097d91a90bd..501620885ccd 100644 --- a/packages/SoundPicker/res/values-ka/strings.xml +++ b/packages/SoundPicker/res/values-ka/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ნაგულისხმევი ზარი"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"შეტყობინების ნაგულისხმევი ხმა"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"მაღვიძარას ნაგულისხმევი ხმა"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ზარის დამატება"</string> <string name="add_alarm_text" msgid="3545497316166999225">"მაღვიძარას დამატება"</string> diff --git a/packages/SoundPicker/res/values-kk/strings.xml b/packages/SoundPicker/res/values-kk/strings.xml index a2ddf5ed05ce..1c74567a0b60 100644 --- a/packages/SoundPicker/res/values-kk/strings.xml +++ b/packages/SoundPicker/res/values-kk/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Әдепкі рингтон"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Әдепкі хабарландыру дыбысы"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Әдепкі дабыл дыбысы"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Рингтон енгізу"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Оятқыш енгізу"</string> diff --git a/packages/SoundPicker/res/values-km/strings.xml b/packages/SoundPicker/res/values-km/strings.xml index dcc202a8e22b..d512bc62e00b 100644 --- a/packages/SoundPicker/res/values-km/strings.xml +++ b/packages/SoundPicker/res/values-km/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"សំឡេងរោទ៍លំនាំដើម"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"សំឡេងជូនដំណឹងលំនាំដើម"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"សំឡេងម៉ោងរោទិ៍លំនាំដើម"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"បន្ថែមសំឡេងរោទ៍"</string> <string name="add_alarm_text" msgid="3545497316166999225">"បញ្ចូលម៉ោងរោទ៍"</string> diff --git a/packages/SoundPicker/res/values-kn/strings.xml b/packages/SoundPicker/res/values-kn/strings.xml index 705dd0d0fed3..030d3f2e5ca7 100644 --- a/packages/SoundPicker/res/values-kn/strings.xml +++ b/packages/SoundPicker/res/values-kn/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ಡಿಫಾಲ್ಟ್ ರಿಂಗ್ಟೋನ್"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ಡೀಫಾಲ್ಟ್ ಅಧಿಸೂಚನೆ ಧ್ವನಿ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ಡೀಫಾಲ್ಟ್ ಅಲಾರಾಂ ಧ್ವನಿ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ರಿಂಗ್ಟೋನ್ ಸೇರಿಸಿ"</string> <string name="add_alarm_text" msgid="3545497316166999225">"ಅಲಾರಾಂ ಸೇರಿಸಿ"</string> diff --git a/packages/SoundPicker/res/values-ko/strings.xml b/packages/SoundPicker/res/values-ko/strings.xml index 6d59034f11da..555434f1f886 100644 --- a/packages/SoundPicker/res/values-ko/strings.xml +++ b/packages/SoundPicker/res/values-ko/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"기본 벨소리"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"기본 알림 소리"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"기본 알람 소리"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"벨소리 추가"</string> <string name="add_alarm_text" msgid="3545497316166999225">"알람 추가"</string> diff --git a/packages/SoundPicker/res/values-ky/strings.xml b/packages/SoundPicker/res/values-ky/strings.xml index bd6c17d00130..5a3ef907fd63 100644 --- a/packages/SoundPicker/res/values-ky/strings.xml +++ b/packages/SoundPicker/res/values-ky/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Демейки шыңгыр"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Билдирменин демейки үнү"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Ойготкучтун демейки үнү"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Шыңгыр кошуу"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Ойготкуч кошуу"</string> diff --git a/packages/SoundPicker/res/values-lo/strings.xml b/packages/SoundPicker/res/values-lo/strings.xml index f225a6ce1032..983ff72493d7 100644 --- a/packages/SoundPicker/res/values-lo/strings.xml +++ b/packages/SoundPicker/res/values-lo/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ຣິງໂທນເລີ່ມຕົ້ນ"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ສຽງແຈ້ງເຕືອນເລີ່ມຕົ້ນ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ສຽງໂມງປຸກຕາມຄ່າເລີ່ມຕົ້ນ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ເພີ່ມຣິງໂທນ"</string> <string name="add_alarm_text" msgid="3545497316166999225">"ເພີ່ມໂມງປຸກ"</string> diff --git a/packages/SoundPicker/res/values-lt/strings.xml b/packages/SoundPicker/res/values-lt/strings.xml index cc1b0e67fd48..0789ea1fb881 100644 --- a/packages/SoundPicker/res/values-lt/strings.xml +++ b/packages/SoundPicker/res/values-lt/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Numatytasis skambėjimo tonas"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Numatytasis pranešimo garsas"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Numatytasis signalo garsas"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Pridėti skambėjimo toną"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Pridėti signalą"</string> diff --git a/packages/SoundPicker/res/values-lv/strings.xml b/packages/SoundPicker/res/values-lv/strings.xml index 421ad0b5c4f3..3d0c5cae6bc1 100644 --- a/packages/SoundPicker/res/values-lv/strings.xml +++ b/packages/SoundPicker/res/values-lv/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Noklusējuma zvana signāls"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Paziņojuma noklusējuma skaņa"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Signāla noklusējuma skaņa"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Pievienot zvana signālu"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Pievienot signālu"</string> diff --git a/packages/SoundPicker/res/values-mk/strings.xml b/packages/SoundPicker/res/values-mk/strings.xml index b5008ce036dc..f39c386a7b78 100644 --- a/packages/SoundPicker/res/values-mk/strings.xml +++ b/packages/SoundPicker/res/values-mk/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Стандардна мелодија"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Стандарден звук за известување"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Стандарден звук за аларм"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Додај мелодија"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Додајте аларм"</string> diff --git a/packages/SoundPicker/res/values-ml/strings.xml b/packages/SoundPicker/res/values-ml/strings.xml index f2d51f53e51e..738d7abb8eea 100644 --- a/packages/SoundPicker/res/values-ml/strings.xml +++ b/packages/SoundPicker/res/values-ml/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ഡിഫോൾട്ട് റിംഗ്ടോൺ"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ഡിഫോൾട്ട് അറിയിപ്പ് ശബ്ദം"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ഡിഫോൾട്ട് അലാറം ശബ്ദം"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"റിംഗ്ടോൺ ചേർക്കുക"</string> <string name="add_alarm_text" msgid="3545497316166999225">"അലാറം ചേർക്കുക"</string> diff --git a/packages/SoundPicker/res/values-mn/strings.xml b/packages/SoundPicker/res/values-mn/strings.xml index e996d19c1a00..cfc81d622de7 100644 --- a/packages/SoundPicker/res/values-mn/strings.xml +++ b/packages/SoundPicker/res/values-mn/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Үндсэн хонхны ая"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Мэдэгдлийн өгөгдмөл ая"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Сэрүүлгийн өгөгдмөл дуу"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Хонхны ая нэмэх"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Сэрүүлэг нэмэх"</string> diff --git a/packages/SoundPicker/res/values-mr/strings.xml b/packages/SoundPicker/res/values-mr/strings.xml index 19ab294a792e..e759eb3e1ffc 100644 --- a/packages/SoundPicker/res/values-mr/strings.xml +++ b/packages/SoundPicker/res/values-mr/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"डीफॉल्ट रिंगटोन"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"डीफॉल्ट सूचना आवाज"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"डीफॉल्ट अलार्म ध्वनी"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"रिंगटोन जोडा"</string> <string name="add_alarm_text" msgid="3545497316166999225">"अलार्म जोडा"</string> diff --git a/packages/SoundPicker/res/values-ms/strings.xml b/packages/SoundPicker/res/values-ms/strings.xml index bda0bdeab9f2..a65f8bc9e926 100644 --- a/packages/SoundPicker/res/values-ms/strings.xml +++ b/packages/SoundPicker/res/values-ms/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Nada dering lalai"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Bunyi pemberitahuan lalai"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Bunyi penggera lalai"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Tambah nada dering"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Tambah penggera"</string> diff --git a/packages/SoundPicker/res/values-my/strings.xml b/packages/SoundPicker/res/values-my/strings.xml index 36225d72d74a..83c44149ad76 100644 --- a/packages/SoundPicker/res/values-my/strings.xml +++ b/packages/SoundPicker/res/values-my/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"မူရင်းမြည်သံ"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"မူရင်းအကြောင်းကြားသံ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"မူရင်းနှိုးစက်သံ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ဖုန်းမြည်သံကို ထည့်ရန်"</string> <string name="add_alarm_text" msgid="3545497316166999225">"နှိုးစက်ထည့်ရန်"</string> diff --git a/packages/SoundPicker/res/values-nb/strings.xml b/packages/SoundPicker/res/values-nb/strings.xml index 726e716d73fe..37d3ee072f07 100644 --- a/packages/SoundPicker/res/values-nb/strings.xml +++ b/packages/SoundPicker/res/values-nb/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Standard ringetone"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Standard varsellyd"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Standard alarmlyd"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Legg til ringelyd"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Legg til en alarm"</string> diff --git a/packages/SoundPicker/res/values-ne/strings.xml b/packages/SoundPicker/res/values-ne/strings.xml index d5f0bf6076c3..0f787cf8b5d4 100644 --- a/packages/SoundPicker/res/values-ne/strings.xml +++ b/packages/SoundPicker/res/values-ne/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"पूर्वनिर्धारित रिङटोन"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"सूचनाको पूर्वनिर्धारित ध्वनि"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"अलार्मका लागि पूर्वनिर्धारित ध्वनि"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"रिङटोन थप्नुहोस्"</string> <string name="add_alarm_text" msgid="3545497316166999225">"अलार्म थप्नुहोस्"</string> diff --git a/packages/SoundPicker/res/values-nl/strings.xml b/packages/SoundPicker/res/values-nl/strings.xml index 998f908f2fad..90f2f788d933 100644 --- a/packages/SoundPicker/res/values-nl/strings.xml +++ b/packages/SoundPicker/res/values-nl/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Standaardbeltoon"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Standaard meldingsgeluid"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Standaard alarmgeluid"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Ringtone toevoegen"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Wekker toevoegen"</string> diff --git a/packages/SoundPicker/res/values-or/strings.xml b/packages/SoundPicker/res/values-or/strings.xml index d06f70bd26be..89dd760afd70 100644 --- a/packages/SoundPicker/res/values-or/strings.xml +++ b/packages/SoundPicker/res/values-or/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ଡିଫଲ୍ଟ ରିଙ୍ଗଟୋନ୍"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ଡିଫଲ୍ଟ ବିଜ୍ଞପ୍ତି ସାଉଣ୍ଡ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ଡିଫଲ୍ଟ ଆଲାର୍ମ ଶବ୍ଦ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ରିଙ୍ଗଟୋନ୍ ଯୋଡ଼ନ୍ତୁ"</string> <string name="add_alarm_text" msgid="3545497316166999225">"ଆଲାର୍ମ ଯୋଗ କରନ୍ତୁ"</string> diff --git a/packages/SoundPicker/res/values-pa/strings.xml b/packages/SoundPicker/res/values-pa/strings.xml index bdd66ed7019d..6946f18fc4e3 100644 --- a/packages/SoundPicker/res/values-pa/strings.xml +++ b/packages/SoundPicker/res/values-pa/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੂਚਨਾ ਧੁਨੀ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਅਲਾਰਮ ਧੁਨੀ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ਰਿੰਗਟੋਨ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="add_alarm_text" msgid="3545497316166999225">"ਅਲਾਰਮ ਸ਼ਾਮਲ ਕਰੋ"</string> diff --git a/packages/SoundPicker/res/values-pl/strings.xml b/packages/SoundPicker/res/values-pl/strings.xml index 0a5b0e61d661..f172659e3d7e 100644 --- a/packages/SoundPicker/res/values-pl/strings.xml +++ b/packages/SoundPicker/res/values-pl/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Dzwonek domyślny"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Domyślny dźwięk powiadomienia"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Domyślny dźwięk alarmu"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Dodaj dzwonek"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Dodaj alarm"</string> diff --git a/packages/SoundPicker/res/values-pt-rBR/strings.xml b/packages/SoundPicker/res/values-pt-rBR/strings.xml index ab7184250238..4fad12754ec7 100644 --- a/packages/SoundPicker/res/values-pt-rBR/strings.xml +++ b/packages/SoundPicker/res/values-pt-rBR/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Toque padrão"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Som de notificação padrão"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Som de alarme padrão"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Adicionar toque"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Adicionar alarme"</string> diff --git a/packages/SoundPicker/res/values-pt-rPT/strings.xml b/packages/SoundPicker/res/values-pt-rPT/strings.xml index 59d35a7341a1..c93ec85a14b7 100644 --- a/packages/SoundPicker/res/values-pt-rPT/strings.xml +++ b/packages/SoundPicker/res/values-pt-rPT/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Toque predefinido"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Som de notificação predefinido"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Som de alarme predefinido"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Adicionar toque"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Adicionar alarme"</string> diff --git a/packages/SoundPicker/res/values-pt/strings.xml b/packages/SoundPicker/res/values-pt/strings.xml index ab7184250238..4fad12754ec7 100644 --- a/packages/SoundPicker/res/values-pt/strings.xml +++ b/packages/SoundPicker/res/values-pt/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Toque padrão"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Som de notificação padrão"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Som de alarme padrão"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Adicionar toque"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Adicionar alarme"</string> diff --git a/packages/SoundPicker/res/values-ro/strings.xml b/packages/SoundPicker/res/values-ro/strings.xml index e072880a0dcf..db39f672ca16 100644 --- a/packages/SoundPicker/res/values-ro/strings.xml +++ b/packages/SoundPicker/res/values-ro/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Ton de apel prestabilit"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Sunet de notificare prestabilit"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Sunet de alarmă prestabilit"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Adăugați un ton de sonerie"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Adăugați o alarmă"</string> diff --git a/packages/SoundPicker/res/values-ru/strings.xml b/packages/SoundPicker/res/values-ru/strings.xml index 92668aea6259..5185bde47c8a 100644 --- a/packages/SoundPicker/res/values-ru/strings.xml +++ b/packages/SoundPicker/res/values-ru/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Мелодия по умолчанию"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Звук уведомления по умолчанию"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Звук будильника по умолчанию"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Добавить рингтон"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Добавить будильник"</string> diff --git a/packages/SoundPicker/res/values-si/strings.xml b/packages/SoundPicker/res/values-si/strings.xml index b375091b2870..c8949a9f8a5d 100644 --- a/packages/SoundPicker/res/values-si/strings.xml +++ b/packages/SoundPicker/res/values-si/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"සුපුරුදු රින්ටෝනය සකසන්න"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"පෙරනිමි දැනුම් දීම් හඬ"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"පෙරනිමි එලාම හඬ"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"නාද රිද්මය එක් කරන්න"</string> <string name="add_alarm_text" msgid="3545497316166999225">"ඇඟවීමක් එක් කරන්න"</string> diff --git a/packages/SoundPicker/res/values-sk/strings.xml b/packages/SoundPicker/res/values-sk/strings.xml index 6838af0d2e3f..9e401bef2382 100644 --- a/packages/SoundPicker/res/values-sk/strings.xml +++ b/packages/SoundPicker/res/values-sk/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Predvolený tón zvonenia"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Predvolený zvuk upozornení"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Predvolený zvuk budíkov"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Pridať tón zvonenia"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Pridať budík"</string> diff --git a/packages/SoundPicker/res/values-sl/strings.xml b/packages/SoundPicker/res/values-sl/strings.xml index a050787d72cb..2261b0313d3c 100644 --- a/packages/SoundPicker/res/values-sl/strings.xml +++ b/packages/SoundPicker/res/values-sl/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Privzeta melodija zvonjenja"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Privzeti zvok obvestila"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Privzeti zvok alarma"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Dodaj ton zvonjenja"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Dodaj alarm"</string> diff --git a/packages/SoundPicker/res/values-sr/strings.xml b/packages/SoundPicker/res/values-sr/strings.xml index 01db396ff628..89fffa863c06 100644 --- a/packages/SoundPicker/res/values-sr/strings.xml +++ b/packages/SoundPicker/res/values-sr/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Подразумевани звук звона"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Подразумевани звук обавештења"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Подразумевани звук аларма"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Додај мелодију звона"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Додајте аларм"</string> diff --git a/packages/SoundPicker/res/values-sv/strings.xml b/packages/SoundPicker/res/values-sv/strings.xml index f6acdd48617f..5eb245502eeb 100644 --- a/packages/SoundPicker/res/values-sv/strings.xml +++ b/packages/SoundPicker/res/values-sv/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Standardringsignal"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Standardljud för aviseringar"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Standardljud för alarm"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Lägg till ringsignal"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Lägg till alarm"</string> diff --git a/packages/SoundPicker/res/values-sw/strings.xml b/packages/SoundPicker/res/values-sw/strings.xml index beb8780e9d15..7a426c4f77ef 100644 --- a/packages/SoundPicker/res/values-sw/strings.xml +++ b/packages/SoundPicker/res/values-sw/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Mlio chaguomsingi"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Sauti chaguomsingi ya arifa"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Sauti chaguomsingi ya kengele"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Ongeza mlio wa simu"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Ongeza kengele"</string> diff --git a/packages/SoundPicker/res/values-ta/strings.xml b/packages/SoundPicker/res/values-ta/strings.xml index 3c9cc5449f3e..b1b80464ba8e 100644 --- a/packages/SoundPicker/res/values-ta/strings.xml +++ b/packages/SoundPicker/res/values-ta/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"இயல்புநிலை ரிங்டோன்"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"இயல்புநிலை அறிவிப்பு ஒலி"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"இயல்பு அலார ஒலி"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"ரிங்டோனைச் சேர்"</string> <string name="add_alarm_text" msgid="3545497316166999225">"அலாரத்தைச் சேர்"</string> diff --git a/packages/SoundPicker/res/values-te/strings.xml b/packages/SoundPicker/res/values-te/strings.xml index e0baa593e61a..142c73c969d2 100644 --- a/packages/SoundPicker/res/values-te/strings.xml +++ b/packages/SoundPicker/res/values-te/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"డిఫాల్ట్ రింగ్టోన్"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"డిఫాల్ట్ నోటిఫికేషన్ ధ్వని"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"డిఫాల్ట్ అలారం ధ్వని"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"రింగ్టోన్ను జోడించు"</string> <string name="add_alarm_text" msgid="3545497316166999225">"అలారాన్ని జోడించు"</string> diff --git a/packages/SoundPicker/res/values-th/strings.xml b/packages/SoundPicker/res/values-th/strings.xml index 098e4dd23e6d..ae98c3cc4d62 100644 --- a/packages/SoundPicker/res/values-th/strings.xml +++ b/packages/SoundPicker/res/values-th/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"เสียงเรียกเข้าเริ่มต้น"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"เสียงแจ้งเตือนเริ่มต้น"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"เสียงปลุกเริ่มต้น"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"เพิ่มเสียงเรียกเข้า"</string> <string name="add_alarm_text" msgid="3545497316166999225">"เพิ่มการปลุก"</string> diff --git a/packages/SoundPicker/res/values-tl/strings.xml b/packages/SoundPicker/res/values-tl/strings.xml index 80b93de9a788..e35c8aa133f1 100644 --- a/packages/SoundPicker/res/values-tl/strings.xml +++ b/packages/SoundPicker/res/values-tl/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Default na ringtone"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Default na notification sound"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Default na tunog ng alarm"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Magdagdag ng ringtone"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Magdagdag ng alarm"</string> diff --git a/packages/SoundPicker/res/values-uk/strings.xml b/packages/SoundPicker/res/values-uk/strings.xml index 4ec70c09bc93..bb71ad019713 100644 --- a/packages/SoundPicker/res/values-uk/strings.xml +++ b/packages/SoundPicker/res/values-uk/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Мелодія за умовчанням"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Стандартний сигнал сповіщень"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Сигнал будильника за умовчанням"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Додати сигнал"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Додати сигнал"</string> diff --git a/packages/SoundPicker/res/values-ur/strings.xml b/packages/SoundPicker/res/values-ur/strings.xml index 0c2dc7af4010..0a4f5ed9a2de 100644 --- a/packages/SoundPicker/res/values-ur/strings.xml +++ b/packages/SoundPicker/res/values-ur/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"ڈیفالٹ رنگ ٹون"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"اطلاع کی ڈیفالٹ آواز"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"الارم کی ڈیفالٹ آواز"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"رنگ ٹون شامل کریں"</string> <string name="add_alarm_text" msgid="3545497316166999225">"الارم شامل کریں"</string> diff --git a/packages/SoundPicker/res/values-uz/strings.xml b/packages/SoundPicker/res/values-uz/strings.xml index 3c7693bd02a0..17d7ed8ac6a0 100644 --- a/packages/SoundPicker/res/values-uz/strings.xml +++ b/packages/SoundPicker/res/values-uz/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Standart rington"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Standart bildirishnoma tovushi"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Standart signal tovushi"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Rington qo‘shish"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Signal qo‘shish"</string> diff --git a/packages/SoundPicker/res/values-vi/strings.xml b/packages/SoundPicker/res/values-vi/strings.xml index e27b6928ff76..c167442aa40c 100644 --- a/packages/SoundPicker/res/values-vi/strings.xml +++ b/packages/SoundPicker/res/values-vi/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Nhạc chuông mặc định"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Âm thanh thông báo mặc định"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Âm thanh báo thức mặc định"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Thêm nhạc chuông"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Thêm báo thức"</string> diff --git a/packages/SoundPicker/res/values-zh-rCN/strings.xml b/packages/SoundPicker/res/values-zh-rCN/strings.xml index 3199803fe7a8..d380a8ec5845 100644 --- a/packages/SoundPicker/res/values-zh-rCN/strings.xml +++ b/packages/SoundPicker/res/values-zh-rCN/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"默认铃声"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"默认通知提示音"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"默认闹钟铃声"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"添加铃声"</string> <string name="add_alarm_text" msgid="3545497316166999225">"添加闹钟"</string> diff --git a/packages/SoundPicker/res/values-zh-rHK/strings.xml b/packages/SoundPicker/res/values-zh-rHK/strings.xml index 6c3b2f83b738..ccc569275f10 100644 --- a/packages/SoundPicker/res/values-zh-rHK/strings.xml +++ b/packages/SoundPicker/res/values-zh-rHK/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"預設鈴聲"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"預設通知音效"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"預設鬧鐘音效"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"加入鈴聲"</string> <string name="add_alarm_text" msgid="3545497316166999225">"新增鬧鐘"</string> diff --git a/packages/SoundPicker/res/values-zh-rTW/strings.xml b/packages/SoundPicker/res/values-zh-rTW/strings.xml index 379c1d5d2e88..b920f7c03230 100644 --- a/packages/SoundPicker/res/values-zh-rTW/strings.xml +++ b/packages/SoundPicker/res/values-zh-rTW/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"預設鈴聲"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"預設通知音效"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"預設鬧鐘音效"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"新增鈴聲"</string> <string name="add_alarm_text" msgid="3545497316166999225">"新增鬧鐘"</string> diff --git a/packages/SoundPicker/res/values-zu/strings.xml b/packages/SoundPicker/res/values-zu/strings.xml index 6c11dc591f3c..fb75d9374d19 100644 --- a/packages/SoundPicker/res/values-zu/strings.xml +++ b/packages/SoundPicker/res/values-zu/strings.xml @@ -17,8 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="ringtone_default" msgid="798836092118824500">"Iringithoni emisiwe"</string> - <!-- no translation found for notification_sound_default (8133121186242636840) --> - <skip /> + <string name="notification_sound_default" msgid="8133121186242636840">"Umsindo wesaziso ozenzakalelayo"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Umsindo we-alamu ozenzakalelayo"</string> <string name="add_ringtone_text" msgid="6642389991738337529">"Engeza ithoni yokukhala"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Engeza i-alamu"</string> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 37900fb13496..1306657ae403 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -674,8 +674,9 @@ android:label="@string/controls_providers_title" android:theme="@style/Theme.ControlsManagement" android:showForAllUsers="true" - android:clearTaskOnLaunch="true" + android:finishOnTaskLaunch="true" android:excludeFromRecents="true" + android:launchMode="singleInstance" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" android:visibleToInstantApps="true"> </activity> @@ -683,6 +684,7 @@ <activity android:name=".controls.management.ControlsEditingActivity" android:theme="@style/Theme.ControlsManagement" android:excludeFromRecents="true" + android:noHistory="true" android:showForAllUsers="true" android:finishOnTaskLaunch="true" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" @@ -694,6 +696,7 @@ android:excludeFromRecents="true" android:showForAllUsers="true" android:finishOnTaskLaunch="true" + android:launchMode="singleInstance" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" android:visibleToInstantApps="true"> </activity> diff --git a/packages/SystemUI/docs/broadcasts.md b/packages/SystemUI/docs/broadcasts.md index 28657f28e53b..6c8488b332c2 100644 --- a/packages/SystemUI/docs/broadcasts.md +++ b/packages/SystemUI/docs/broadcasts.md @@ -30,10 +30,21 @@ Additionally, the dispatcher supports the following: If introducing a new `BroadcastReceiver` (not declared in `AndroidManifest`) that satisfies the constraints above, use the dispatcher to reduce the load on `system_server`. -Do not use the dispatcher to obtain the last broadcast (by passing a null `BroadcastReceiver`). `BroadcastDispatcher#registerReceiver` **does not** return the last sticky Intent. - Additionally, if listening to some broadcast is latency critical (beyond 100ms of latency), consider registering with Context instead. +### A note on sticky broadcasts + +Sticky broadcasts are those that have been sent using `Context#sendStickyBroadcast` or `Context#sendStickyBroadcastAsUser`. In general they behave like regular broadcasts, but they are also cached (they may be replaced later) to provide the following two features: + * They may be returned by `Context#registerReceiver` if the broadcast is matched by the `IntentFilter`. In case that multiple cached broadcast match the filter, any one of those may be returned. + * All cached sticky broadcasts that match the filter will be sent to the just registered `BroadcastReceiver#onReceive`. + +Sticky broadcasts are `@Deprecated` since API 24 and the general recommendation is to use regular broadcasts and API that allows to retrieve last known state. + +Because of this and in order to provide the necessary optimizations, `BroadcastDispatcher` does not offer support for sticky intents: + +* Do not use the dispatcher to obtain the last broadcast (by passing a null `BroadcastReceiver`). `BroadcastDispatcher#registerReceiver` **does not** return the last sticky Intent. +* Do not expect cached sticky broadcasts to be delivered on registration. This may happen but it's not guaranteed. + ## How do I use the dispatcher? Acquire the dispatcher by using `@Inject` to obtain a `BroadcastDispatcher`. Then, use the following methods in that instance. diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml index 4989e91ac028..456088181d7f 100644 --- a/packages/SystemUI/res-keyguard/values-kk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml @@ -70,7 +70,7 @@ <string name="kg_pattern_instructions" msgid="5376036737065051736">"Өрнекті енгізіңіз"</string> <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"SIM PIN кодын енгізіңіз."</string> <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" үшін SIM PIN кодын енгізіңіз."</string> - <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Құрылығыны мобильдік байланыс қызметінсіз пайдалану үшін eSIM картасын өшіріңіз."</string> + <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Құрылғыны мобильдік байланыс қызметінсіз пайдалану үшін eSIM картасын өшіріңіз."</string> <string name="kg_pin_instructions" msgid="822353548385014361">"PIN кодын енгізіңіз"</string> <string name="kg_password_instructions" msgid="324455062831719903">"Кілтсөзді енгізіңіз"</string> <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. Толығырақ ақпаратты оператордан алыңыз."</string> diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml index d956a79cb496..d7f4015be92d 100644 --- a/packages/SystemUI/res-keyguard/values-ky/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml @@ -80,7 +80,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"SIM-карта бөгөттөн чыгарылууда…"</string> <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4–8 сандан турган PIN-кодду териңиз."</string> <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-код 8 же андан көп сандан турушу керек."</string> - <string name="kg_invalid_puk" msgid="1774337070084931186">"PUK-кодду кайрадан туура киргизиңиз. Кайталанган аракеттер SIM-картаны биротоло жараксыз кылат."</string> + <string name="kg_invalid_puk" msgid="1774337070084931186">"PUK-кодду кайрадан туура киргизиңиз. Кайталанган аракеттер SIM картаны биротоло жараксыз кылат."</string> <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Өтө көп графикалык ачкычты тартуу аракети болду"</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string> diff --git a/packages/SystemUI/res-product/values-fr-rCA/strings.xml b/packages/SystemUI/res-product/values-fr-rCA/strings.xml index e56234bad207..a056b8721ee4 100644 --- a/packages/SystemUI/res-product/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res-product/values-fr-rCA/strings.xml @@ -20,7 +20,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Réalignez le téléphone pour le recharger plus rapidement"</string> - <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Réalignez le téléphone pour effectuer la recharge sans fil"</string> + <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Réalignez le téléphone pour le recharger sans fil"</string> <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"L\'appareil Android TV va bientôt s\'éteindre. Appuyez sur un bouton pour le laisser allumé."</string> <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"L\'appareil va bientôt s\'éteindre. Interagissez avec lui pour le laisser allumé."</string> <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"Aucune carte SIM n\'est insérée dans la tablette."</string> diff --git a/packages/SystemUI/res-product/values-fr/strings.xml b/packages/SystemUI/res-product/values-fr/strings.xml index 075d5ef2142d..8325fb837a25 100644 --- a/packages/SystemUI/res-product/values-fr/strings.xml +++ b/packages/SystemUI/res-product/values-fr/strings.xml @@ -19,7 +19,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Réalignez le téléphone pour le recharger plus rapidement"</string> + <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Réalignez le téléphone pour une recharge plus rapide"</string> <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Réalignez le téléphone pour le recharger sans fil"</string> <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"L\'appareil Android TV va bientôt passer en mode Veille. Appuyez sur un bouton pour qu\'il reste allumé."</string> <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"L\'appareil va bientôt passer en mode Veille. Appuyez dessus pour qu\'il reste allumé."</string> diff --git a/packages/SystemUI/res-product/values-hi/strings.xml b/packages/SystemUI/res-product/values-hi/strings.xml index 188a4104cab4..c0ff7d89c2ee 100644 --- a/packages/SystemUI/res-product/values-hi/strings.xml +++ b/packages/SystemUI/res-product/values-hi/strings.xml @@ -19,8 +19,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"फ़ोन को फ़ास्ट चार्ज करने के लिए डॉक पर ठीक तरह से रखें"</string> - <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"फ़ोन को वायरलेस चार्जिंग के लिए डॉक पर ठीक तरह से रखें"</string> + <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"फ़ोन को फ़ास्ट चार्ज करने के लिए, डॉक पर ठीक तरह से रखें"</string> + <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"वायरलेस चार्जिंग के लिए, फ़ोन को डॉक पर ठीक तरह से रखें"</string> <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए किसी बटन को दबाएं."</string> <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए किसी बटन को दबाएं."</string> <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"टैबलेट में कोई SIM कार्ड नहीं है."</string> diff --git a/packages/SystemUI/res-product/values-zh-rCN/strings.xml b/packages/SystemUI/res-product/values-zh-rCN/strings.xml index 56c461c7d28c..09d84ff59d21 100644 --- a/packages/SystemUI/res-product/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res-product/values-zh-rCN/strings.xml @@ -20,7 +20,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"请重新调整手机位置以便更快速地充电"</string> - <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"请重新调整手机位置以便进行无线充电"</string> + <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"请调整手机位置以便进行无线充电"</string> <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV 设备即将关闭;按一下相应的按钮即可让设备保持开启状态。"</string> <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"设备即将关闭;按一下即可让设备保持开启状态。"</string> <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"平板电脑中没有 SIM 卡。"</string> diff --git a/packages/SystemUI/res-product/values-zh-rTW/strings.xml b/packages/SystemUI/res-product/values-zh-rTW/strings.xml index 8b3b1213b0b8..1575d27abf2f 100644 --- a/packages/SystemUI/res-product/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res-product/values-zh-rTW/strings.xml @@ -20,7 +20,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"請調整手機的位置,以便提高充電效率"</string> - <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"請調整手機的位置,以便進行無線充電"</string> + <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"請調整手機位置,即可無線充電"</string> <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV 裝置即將關閉。如要讓裝置保持開啟狀態,請按下任一按鈕。"</string> <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"裝置即將關閉。如要讓裝置保持開啟狀態,請輕觸螢幕或按下任一按鈕。"</string> <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"平板電腦中沒有 SIM 卡。"</string> diff --git a/packages/SystemUI/res/color/control_foreground.xml b/packages/SystemUI/res/color/control_foreground.xml index 339f1e20b8b9..de702cdc0263 100644 --- a/packages/SystemUI/res/color/control_foreground.xml +++ b/packages/SystemUI/res/color/control_foreground.xml @@ -2,5 +2,5 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:color="@color/control_default_foreground" /> - <item android:color="@color/GM2_blue_200" /> + <item android:color="@color/control_enabled_default_foreground" /> </selector> diff --git a/packages/SystemUI/res/color/thermo_cool_foreground.xml b/packages/SystemUI/res/color/thermo_cool_foreground.xml index 339f1e20b8b9..ffce33acfcf7 100644 --- a/packages/SystemUI/res/color/thermo_cool_foreground.xml +++ b/packages/SystemUI/res/color/thermo_cool_foreground.xml @@ -2,5 +2,5 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:color="@color/control_default_foreground" /> - <item android:color="@color/GM2_blue_200" /> + <item android:color="@color/control_enabled_cool_foreground" /> </selector> diff --git a/packages/SystemUI/res/color/thermo_heat_foreground.xml b/packages/SystemUI/res/color/thermo_heat_foreground.xml index ffcf55098103..f6ebd0bfdcba 100644 --- a/packages/SystemUI/res/color/thermo_heat_foreground.xml +++ b/packages/SystemUI/res/color/thermo_heat_foreground.xml @@ -2,5 +2,5 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:color="@color/control_default_foreground" /> - <item android:color="@color/GM2_red_200" /> + <item android:color="@color/control_enabled_heat_foreground" /> </selector> diff --git a/packages/SystemUI/res/drawable/ic_device_lock_off.xml b/packages/SystemUI/res/drawable/ic_device_lock_off.xml index a2662ff7f6bb..15ac5245a9e7 100644 --- a/packages/SystemUI/res/drawable/ic_device_lock_off.xml +++ b/packages/SystemUI/res/drawable/ic_device_lock_off.xml @@ -20,7 +20,7 @@ android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M18,8H17V6C17,4.6739 16.4732,3.402 15.5355,2.4644C14.5979,1.5267 13.3261,1 12,1C10.6739,1 9.4021,1.5267 8.4645,2.4644C7.5268,3.402 7,4.6739 7,6V8H6C5.47,8.0016 4.9623,8.2127 4.5875,8.5874C4.2128,8.9621 4.0016,9.47 4,10V20C4.0016,20.5299 4.2128,21.0379 4.5875,21.4126C4.9623,21.7873 5.47,21.9984 6,22H18C18.5299,21.9984 19.0377,21.7873 19.4125,21.4126C19.7872,21.0379 19.9984,20.5299 20,20V10C19.9984,9.47 19.7872,8.9621 19.4125,8.5874C19.0377,8.2127 18.5299,8.0016 18,8ZM9,6C9,5.2043 9.3161,4.4415 9.8787,3.8789C10.4413,3.3163 11.2044,3 12,3C12.7956,3 13.5587,3.3163 14.1213,3.8789C14.6839,4.4415 15,5.2043 15,6V8H9V6ZM18,20H6V10H18V20Z" + android:pathData="M18,8H17V6C17,4.6739 16.4732,3.402 15.5355,2.4644C14.5979,1.5267 13.3261,1 12,1C10.6739,1 9.4021,1.5267 8.4645,2.4644C7.5268,3.402 7,4.6739 7,6H8.9C8.9,5.1778 9.2266,4.3892 9.808,3.8079C10.3893,3.2265 11.1778,2.8999 12,2.8999C12.8222,2.8999 13.6107,3.2265 14.192,3.8079C14.7734,4.3892 15.1,5.1778 15.1,6V8H6C5.47,8.0016 4.9623,8.2129 4.5875,8.5877C4.2128,8.9624 4.0016,9.47 4,10V20C4.0016,20.5299 4.2128,21.0376 4.5875,21.4124C4.9623,21.7871 5.47,21.9984 6,22H18C18.5299,21.9984 19.0377,21.7871 19.4125,21.4124C19.7872,21.0376 19.9984,20.5299 20,20V10C19.9984,9.47 19.7872,8.9624 19.4125,8.5877C19.0377,8.2129 18.5299,8.0016 18,8ZM18,20H6V10H18V20Z" android:fillColor="#FF000000" /> <path android:pathData="M12,17C13.1046,17 14,16.1046 14,15C14,13.8954 13.1046,13 12,13C10.8954,13 10,13.8954 10,15C10,16.1046 10.8954,17 12,17Z" diff --git a/packages/SystemUI/res/drawable/ic_hardware_speaker.xml b/packages/SystemUI/res/drawable/ic_hardware_speaker.xml new file mode 100644 index 000000000000..0081e56a45f2 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_hardware_speaker.xml @@ -0,0 +1,24 @@ +<!-- + Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="18dp" + android:height="18dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M17,2L7,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,1.99 2,1.99L17,22c1.1,0 2,-0.9 2,-2L19,4c0,-1.1 -0.9,-2 -2,-2zM7,20L7,4h10v16L7,20zM12,9c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2c-1.11,0 -2,0.9 -2,2s0.89,2 2,2zM12,11c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z" + android:fillColor="#000000"/> +</vector> diff --git a/packages/SystemUI/res/layout-land/auth_credential_password_view.xml b/packages/SystemUI/res/layout-land/auth_credential_password_view.xml new file mode 100644 index 000000000000..d89f329039c6 --- /dev/null +++ b/packages/SystemUI/res/layout-land/auth_credential_password_view.xml @@ -0,0 +1,61 @@ +<!-- + ~ Copyright (C) 2020 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<com.android.systemui.biometrics.AuthCredentialPasswordView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:gravity="center_horizontal" + android:elevation="@dimen/biometric_dialog_elevation"> + + <TextView + android:id="@+id/title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/TextAppearance.AuthCredential.Title"/> + + <TextView + android:id="@+id/subtitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/TextAppearance.AuthCredential.Subtitle"/> + + <TextView + android:id="@+id/description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/TextAppearance.AuthCredential.Description"/> + + <EditText + android:id="@+id/lockPassword" + android:layout_width="208dp" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:minHeight="48dp" + android:gravity="center" + android:inputType="textPassword" + android:maxLength="500" + android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii" + style="@style/TextAppearance.AuthCredential.PasswordEntry"/> + + <TextView + android:id="@+id/error" + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/TextAppearance.AuthCredential.Error"/> + +</com.android.systemui.biometrics.AuthCredentialPasswordView>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/auth_credential_password_view.xml b/packages/SystemUI/res/layout/auth_credential_password_view.xml index 45638ce5e744..1e0ce0026d8e 100644 --- a/packages/SystemUI/res/layout/auth_credential_password_view.xml +++ b/packages/SystemUI/res/layout/auth_credential_password_view.xml @@ -55,7 +55,7 @@ android:layout_height="0dp" android:layout_weight="1"/> - <EditText + <ImeAwareEditText android:id="@+id/lockPassword" android:layout_width="208dp" android:layout_height="wrap_content" diff --git a/packages/SystemUI/res/layout/controls_dialog_pin.xml b/packages/SystemUI/res/layout/controls_dialog_pin.xml index afef5eaa3979..832c48e509f5 100644 --- a/packages/SystemUI/res/layout/controls_dialog_pin.xml +++ b/packages/SystemUI/res/layout/controls_dialog_pin.xml @@ -26,7 +26,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="48dp" - android:hint="@string/controls_pin_instructions" android:inputType="numberPassword" /> <CheckBox android:id="@+id/controls_pin_use_alpha" diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml index 66f57fd6f37c..fb57b47f63a0 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml @@ -30,6 +30,7 @@ > <RelativeLayout android:id="@+id/global_actions_overflow_button" + android:contentDescription="@string/accessibility_menu" android:layout_width="48dp" android:layout_height="48dp" > diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml index db109fe8a541..94a6bc566e73 100644 --- a/packages/SystemUI/res/layout/global_screenshot.xml +++ b/packages/SystemUI/res/layout/global_screenshot.xml @@ -38,6 +38,7 @@ android:elevation="1dp" android:fillViewport="true" android:layout_marginHorizontal="@dimen/screenshot_action_container_margin_horizontal" + android:layout_marginBottom="@dimen/screenshot_action_container_offset_y" android:gravity="center" android:paddingLeft="@dimen/screenshot_action_container_padding_left" android:paddingRight="@dimen/screenshot_action_container_padding_right" diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml index 6b94befad0f8..bd91ddb5f406 100644 --- a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml +++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml @@ -16,14 +16,15 @@ --> <com.android.systemui.screenshot.ScreenshotActionChip xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/global_screenshot_action_chip" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginRight="@dimen/screenshot_action_chip_margin_right" - android:layout_gravity="center" - android:paddingVertical="@dimen/screenshot_action_chip_padding_vertical" - android:background="@drawable/action_chip_background" - android:gravity="center"> + android:id="@+id/global_screenshot_action_chip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginRight="@dimen/screenshot_action_chip_margin_right" + android:layout_gravity="center" + android:paddingVertical="@dimen/screenshot_action_chip_padding_vertical" + android:background="@drawable/action_chip_background" + android:alpha="0" + android:gravity="center"> <ImageView android:id="@+id/screenshot_action_chip_icon" android:layout_width="@dimen/screenshot_action_chip_icon_size" diff --git a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml new file mode 100644 index 000000000000..e6f27904ee58 --- /dev/null +++ b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<com.android.systemui.statusbar.notification.row.HybridConversationNotificationView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical|start" + android:paddingEnd="12dp"> + + <FrameLayout + android:layout_width="@*android:dimen/conversation_content_start" + android:layout_height="36dp" + > + <ImageView + android:id="@*android:id/conversation_icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="center" + /> + + <ViewStub + android:id="@*android:id/conversation_face_pile" + android:layout="@*android:layout/conversation_face_pile_layout" + android:layout_width="36dp" + android:layout_height="36dp" + android:layout_gravity="center" + /> + </FrameLayout> + + <TextView + android:id="@+id/notification_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + + android:paddingEnd="8dp" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title" + /> + + <TextView + android:id="@+id/conversation_notification_sender" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + style="?attr/hybridNotificationTextStyle" + /> + + <TextView + android:id="@+id/notification_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + style="?attr/hybridNotificationTextStyle" + /> +</com.android.systemui.statusbar.notification.row.HybridConversationNotificationView>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/partial_conversation_info.xml b/packages/SystemUI/res/layout/partial_conversation_info.xml new file mode 100644 index 000000000000..2401dfbc2435 --- /dev/null +++ b/packages/SystemUI/res/layout/partial_conversation_info.xml @@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2020, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<com.android.systemui.statusbar.notification.row.PartialConversationInfo + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/notification_guts" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:focusable="true" + android:clipChildren="false" + android:clipToPadding="true" + android:orientation="vertical" + android:paddingStart="@*android:dimen/notification_content_margin_start"> + + <!-- Package Info --> + <LinearLayout + android:id="@+id/header" + android:layout_width="match_parent" + android:layout_height="@dimen/notification_guts_conversation_header_height" + android:gravity="center_vertical" + android:clipChildren="false" + android:clipToPadding="false"> + <ImageView + android:id="@+id/conversation_icon" + android:layout_width="@dimen/notification_guts_conversation_icon_size" + android:layout_height="@dimen/notification_guts_conversation_icon_size" + android:layout_centerVertical="true" + android:layout_alignParentStart="true" + android:layout_marginEnd="15dp" /> + <LinearLayout + android:id="@+id/names" + android:layout_weight="1" + android:layout_width="0dp" + android:orientation="vertical" + + android:layout_height="wrap_content" + android:minHeight="@dimen/notification_guts_conversation_icon_size" + android:layout_centerVertical="true" + android:gravity="center_vertical" + android:layout_alignEnd="@id/conversation_icon" + android:layout_toEndOf="@id/conversation_icon"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="start" + android:orientation="horizontal"> + <TextView + android:id="@+id/name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@style/TextAppearance.NotificationImportanceChannel"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + style="@style/TextAppearance.NotificationImportanceHeader" + android:layout_marginStart="2dp" + android:layout_marginEnd="2dp" + android:text="@*android:string/notification_header_divider_symbol" /> + <TextView + android:id="@+id/parent_channel_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@style/TextAppearance.NotificationImportanceChannel"/> + + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="start" + android:orientation="horizontal"> + <TextView + android:id="@+id/pkg_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@style/TextAppearance.NotificationImportanceChannelGroup" + android:ellipsize="end" + android:maxLines="1"/> + <TextView + android:id="@+id/group_divider" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + style="@style/TextAppearance.NotificationImportanceHeader" + android:layout_marginStart="2dp" + android:layout_marginEnd="2dp" + android:text="@*android:string/notification_header_divider_symbol" /> + <TextView + android:id="@+id/group_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + style="@style/TextAppearance.NotificationImportanceChannelGroup"/> + </LinearLayout> + <TextView + android:id="@+id/delegate_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + style="@style/TextAppearance.NotificationImportanceHeader" + android:layout_marginStart="2dp" + android:layout_marginEnd="2dp" + android:ellipsize="end" + android:text="@string/notification_delegate_header" + android:maxLines="1" /> + + </LinearLayout> + + <!-- end aligned fields --> + <ImageButton + android:id="@+id/info" + android:layout_width="@dimen/notification_importance_toggle_size" + android:layout_height="@dimen/notification_importance_toggle_size" + android:layout_centerVertical="true" + android:background="@drawable/ripple_drawable" + android:contentDescription="@string/notification_more_settings" + android:src="@drawable/ic_settings" + android:layout_alignParentEnd="true" + android:tint="@color/notification_guts_link_icon_tint"/> + + </LinearLayout> + + <LinearLayout + android:id="@+id/inline_controls" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingEnd="@*android:dimen/notification_content_margin_end" + android:layout_marginTop="@dimen/notification_guts_option_vertical_padding" + android:clipChildren="false" + android:clipToPadding="false" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false" + android:orientation="horizontal"> + <ImageView + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:contentDescription="@null" + android:src="@drawable/ic_info" + android:tint="?android:attr/textColorPrimary" + android:layout_marginEnd="8dp"/> + <TextView + android:id="@+id/non_configurable_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/TextAppearance.NotificationImportanceChannelGroup" /> + </LinearLayout> + + <RelativeLayout + android:id="@+id/bottom_buttons" + android:layout_width="match_parent" + android:layout_height="60dp" + android:gravity="center_vertical" + android:paddingStart="4dp" + android:paddingEnd="4dp" + > + <TextView + android:id="@+id/turn_off_notifications" + android:text="@string/inline_turn_off_notifications" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:gravity="start|center_vertical" + android:minWidth="@dimen/notification_importance_toggle_size" + android:minHeight="@dimen/notification_importance_toggle_size" + android:maxWidth="200dp" + style="@style/TextAppearance.NotificationInfo.Button"/> + <TextView + android:id="@+id/done" + android:text="@string/inline_done_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:gravity="end|center_vertical" + android:minWidth="@dimen/notification_importance_toggle_size" + android:minHeight="@dimen/notification_importance_toggle_size" + android:maxWidth="125dp" + style="@style/TextAppearance.NotificationInfo.Button"/> + </RelativeLayout> + + </LinearLayout> +</com.android.systemui.statusbar.notification.row.PartialConversationInfo> diff --git a/packages/SystemUI/res/layout/qs_media_panel.xml b/packages/SystemUI/res/layout/qs_media_panel.xml index e5ac5f89cd25..a194569dcca4 100644 --- a/packages/SystemUI/res/layout/qs_media_panel.xml +++ b/packages/SystemUI/res/layout/qs_media_panel.xml @@ -119,6 +119,7 @@ android:id="@+id/media_seamless" android:background="@*android:drawable/media_seamless_background" android:layout_weight="1" + android:forceHasOverlappingRendering="false" > <ImageView android:layout_width="@dimen/qs_seamless_icon_size" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 1008d2bb24fd..48248e1c24d0 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Beheer borrels enige tyd"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tik op Bestuur om borrels vanaf hierdie program af te skakel"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Het dit"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-instellings"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Bystandmodus"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 7e2ec10fd90d..d3dd22b2c8d8 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"በማንኛውም ጊዜ አረፋዎችን ይቆጣጠሩ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"የዚህ መተግበሪያ አረፋዎችን ለማጥፋት አቀናብርን መታ ያድርጉ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ገባኝ"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"የ<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ቅንብሮች"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ተጠባባቂ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 0ada0dc0f9c8..dd108d0497fc 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -1019,15 +1019,14 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"التحكّم في فقاعات المحادثات في أي وقت"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"انقر على \"إدارة\" لإيقاف فقاعات المحادثات من هذا التطبيق."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"حسنًا"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"إعدادات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"وضع الاستعداد"</string> <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"تظهر في أعلى قسم المحادثات"</string> - <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"إظهار صورة الملف الشخصي على شاشة القفل"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"تظهر صورة الملف الشخصي على شاشة القفل"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"تظهر كفقاعة عائمة فوق التطبيقات"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"مقاطعة ميزة \"عدم الإزعاج\""</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"لا تتقيّد بميزة \"عدم الإزعاج\""</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"حسنًا"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"نافذة تراكب التكبير"</string> <string name="magnification_window_title" msgid="4863914360847258333">"نافذة التكبير"</string> diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml index 4b5005539c93..76403ab1a4ee 100644 --- a/packages/SystemUI/res/values-ar/strings_tv.xml +++ b/packages/SystemUI/res/values-ar/strings_tv.xml @@ -19,7 +19,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="notification_channel_tv_pip" msgid="844249465483874817">"صورة داخل صورة"</string> + <string name="notification_channel_tv_pip" msgid="844249465483874817">"نافذة ضمن النافذة"</string> <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(ليس هناك عنوان للبرنامج)"</string> <string name="pip_close" msgid="5775212044472849930">"إغلاق PIP"</string> <string name="pip_fullscreen" msgid="3877997489869475181">"ملء الشاشة"</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 99cc25d63834..64d89125ef4e 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"যিকোনো সময়তে bubbles নিয়ন্ত্ৰণ কৰক"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই এপ্টোৰ পৰা bubbles অফ কৰিবলৈ পৰিচালনা কৰকত টিপক"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"বুজি পালোঁ"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ছেটিংসমূহ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ষ্টেণ্ডবাই"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"বাৰ্তালাপ শাখাটোৰ শীৰ্ষত দেখুৱাওক"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"লক স্ক্ৰীনত প্ৰ\'ফাইল-চিত্ৰ দেখুৱাওক"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"এপ্সমূহৰ ওপৰত ওপঙা বাবল হিচাপে দেখা পোৱা যাব"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"অসুবিধা নিদিব সুবিধাটোত ব্যাঘাত জন্মাওক"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"বুজি পালোঁ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"বিবৰ্ধন অ’ভাৰলে’ৰ ৱিণ্ড’"</string> <string name="magnification_window_title" msgid="4863914360847258333">"বিবৰ্ধন ৱিণ্ড’"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"বিবৰ্ধন ৱিণ্ড’ৰ নিয়ন্ত্ৰণসমূহ"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index bbb51e140252..708d79b6aed0 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Yumrucuqları istənilən vaxt idarə edin"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu tətbiqdə yumrucuqları deaktiv etmək üçün \"İdarə edin\" seçiminə toxunun"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gözləmə rejimi"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index cef3cceb9cdc..76e30cadad66 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -1004,8 +1004,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolišite oblačiće u bilo kom trenutku"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljajte da biste isključili oblačiće iz ove aplikacije"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Važi"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Podešavanja za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index a4aea02f98aa..40c083e98936 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -1009,8 +1009,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Кіруйце ўсплывальнымі апавяшчэннямі ў любы час"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Каб выключыць усплывальныя апавяшчэнні з гэтай праграмы, націсніце \"Кіраваць\""</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Зразумела"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Налады \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 9a505cbb8d92..4393f9524272 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Управление на балончетата по всяко време"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Докоснете „Управление“, за да изключите балончетата от това приложение"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Разбрах"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Настройки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index ca0296415510..a04f5c2ed88c 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"যেকোনও সময় বাবল নিয়ন্ত্রণ করুন"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই অ্যাপ থেকে বাবল বন্ধ করতে ম্যানেজ করুন বিকল্প ট্যাপ করুন"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"বুঝেছি"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> সেটিংস"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"কথোপকথনের বিভাগের উপরে দেখান"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"লক স্ক্রিনে প্রোফাইল ছবি দেখান"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"অ্যাপের উপরে একটি ভাসমান বুদবুদ হিসেবে দেখা যাবে"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"বিরক্ত করবে না মোডে ব্যাঘাত ঘটাতে পারে"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"বুঝেছি"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"ওভারলে উইন্ডো বড় করে দেখা"</string> <string name="magnification_window_title" msgid="4863914360847258333">"উইন্ডো বড় করে দেখা"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"উইন্ডো কন্ট্রোল বড় করে দেখা"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 4692c0bd4400..28dda35c178e 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -101,7 +101,7 @@ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Snimanje ekrana"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Snimanje ekrana i zvuka"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Prikaži dodire na ekranu"</string> - <string name="screenrecord_stop_text" msgid="6549288689506057686">"Dodirnite za zaustavljanje"</string> + <string name="screenrecord_stop_text" msgid="6549288689506057686">"Dodirnite da zaustavite"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Zaustavi"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"Pauza"</string> <string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string> @@ -511,7 +511,7 @@ <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string> <string name="manage_notifications_history_text" msgid="57055985396576230">"Historija"</string> <string name="notification_section_header_gentle" msgid="3044910806569985386">"Nečujna obavještenja"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"Obavještenja koja privlače pažnju"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"Zvučna obavještenja"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obriši sva nečujna obavještenja"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obavještenja su pauzirana načinom rada Ne ometaj"</string> @@ -1006,7 +1006,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljajte oblačićima u svakom momentu"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljaj da isključite oblačiće iz ove aplikacije"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumijem"</string> - <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke aplikacije <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Postavke da ažurirate navigiranje sistemom"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 3697151f900a..1d08662b3e0a 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -416,13 +416,13 @@ <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Llum nocturna"</string> <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Al vespre"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Fins a l\'alba"</string> - <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"S\'activarà a les <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Activat a les <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tema fosc"</string> <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Estalvi de bateria"</string> <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Al vespre"</string> <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fins a l\'alba"</string> - <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"S\'activarà a les <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activat a les <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"L\'NFC està desactivada"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla les bombolles en qualsevol moment"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestiona per desactivar les bombolles d\'aquesta aplicació"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entesos"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuració de l\'aplicació <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ves a Configuració per actualitzar el sistema de navegació"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index f996cb9fe152..76390f0e04f7 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -33,7 +33,7 @@ <string name="invalid_charger_title" msgid="938685362320735167">"Enheden kan ikke oplades via USB"</string> <string name="invalid_charger_text" msgid="2339310107232691577">"Brug den oplader, der fulgte med din enhed"</string> <string name="battery_low_why" msgid="2056750982959359863">"Indstillinger"</string> - <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Vil du slå Batterisparefunktion til?"</string> + <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Vil du aktivere Batterisparefunktion?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Om Batterisparefunktion"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktivér"</string> <string name="battery_saver_start_action" msgid="4553256017945469937">"Aktivér batterisparefunktion"</string> @@ -961,7 +961,7 @@ <string name="qs_dnd_replace" msgid="7712119051407052689">"Erstat"</string> <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps, der kører i baggrunden"</string> <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tryk for at se info om batteri- og dataforbrug"</string> - <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vil du slå mobildata fra?"</string> + <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vil du deaktivere mobildata?"</string> <string name="mobile_data_disable_message" msgid="8604966027899770415">"Du vil ikke have data- eller internetadgang via <xliff:g id="CARRIER">%s</xliff:g>. Der vil kun være adgang til internettet via Wi-Fi."</string> <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"dit mobilselskab"</string> <string name="touch_filtered_warning" msgid="8119511393338714836">"Indstillinger kan ikke bekræfte dit svar, da en app dækker for en anmodning om tilladelse."</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bobler når som helst"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryk på Administrer for at deaktivere bobler fra denne app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Indstillinger for <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Indstillinger for at opdatere systemnavigationen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 31837eded54a..82b778eeffc7 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bubble-Einstellungen festlegen"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tippe auf \"Verwalten\", um Bubbles für diese App zu deaktivieren"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Einstellungen für <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemsteuerungseinstellungen wurden angepasst. Änderungen kannst du in den Einstellungen vornehmen."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gehe zu den Einstellungen, um die Systemsteuerung anzupassen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index b3142e9b9616..c1df6d54e2f6 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ελέγξτε τα συννεφάκια ανά πάσα στιγμή."</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Πατήστε Διαχείριση για να απενεργοποιήσετε τα συννεφάκια από αυτήν την εφαρμογή."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Το κατάλαβα."</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Ρυθμίσεις <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 879fc35811a3..53dda2fe729f 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en todo momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Presiona Administrar para desactivar las burbujas de esta app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Configuración para actualizar la navegación del sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 7e3fdc7868da..01fdb37efde9 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en cualquier momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestionar para desactivar las burbujas de esta aplicación"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Ajustes de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Ajustes para actualizar la navegación del sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index fa6447b20e71..5966e0d7930c 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -416,7 +416,7 @@ <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Öövalgus"</string> <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Sissel. päikeselooj."</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Kuni päikesetõusuni"</string> - <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Sisselülitam. kell <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Sisse kell <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Kuni <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tume teema"</string> <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Akusäästja"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Juhtige mulle igal ajal"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Selle rakenduse puhul mullide väljalülitamiseks puudutage valikut Haldamine"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selge"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Rakenduse <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> seaded"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ooterežiim"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 5860af67e0e1..2b2959e22825 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کنترل ابزارک اعلان در هرزمانی"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"برای خاموش کردن «ابزارک اعلان» از این برنامه، روی «مدیریت» ضربه بزنید"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"متوجهام"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"تنظیمات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"پیمایش سیستم بهروزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"برای بهروزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"آمادهبهکار"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 04204535dc08..4bab845eaf38 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Muuta kuplien asetuksia milloin tahansa"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Valitse Hallinnoi, jos haluat poistaa kuplat käytöstä tästä sovelluksesta"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selvä"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: asetukset"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Vaihda järjestelmän navigointitapaa asetuksista"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Virransäästötila"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index da44d8894251..6917db510491 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -36,7 +36,7 @@ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Activer l\'économiseur de pile?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"À propos du mode Économiseur de pile"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activer"</string> - <string name="battery_saver_start_action" msgid="4553256017945469937">"Activer la fonction Économiseur de pile"</string> + <string name="battery_saver_start_action" msgid="4553256017945469937">"Activer l\'économiseur de pile"</string> <string name="status_bar_settings_settings_button" msgid="534331565185171556">"Paramètres"</string> <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation auto de l\'écran"</string> @@ -101,7 +101,7 @@ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Enregistrement de l\'écran"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Enregistrement de l\'écran et de l\'audio"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Afficher les endroits touchés à l\'écran"</string> - <string name="screenrecord_stop_text" msgid="6549288689506057686">"Toucher pour arrêter"</string> + <string name="screenrecord_stop_text" msgid="6549288689506057686">"Touchez ici pour arrêter"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Arrêter"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"Pause"</string> <string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprendre"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 0899e0971af4..8ef8334acdbc 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Contrôler les paramètres des bulles"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Appuyez sur \"Gérer\" pour désactiver les bulles de cette application"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez aux paramètres pour mettre à jour la navigation système"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Mode Veille imminent"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 2e910c77f346..bb5ee8e78593 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlar as burbullas en calquera momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Para desactivar as burbullas nesta aplicación, toca Xestionar"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Para actualizar a navegación do sistema, vai a Configuración"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string> @@ -1008,7 +1007,7 @@ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar imaxe do perfil na pantalla de bloqueo"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Mostrar como burbulla flotante sobre outras apps"</string> <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper modo Non molestar"</string> - <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Listo"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Ampliación da ventá de superposición"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ventá de superposición"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controis de ampliación da ventá"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 715c40b93c4a..fb539003ae40 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -345,7 +345,7 @@ <string name="quick_settings_dnd_alarms_label" msgid="1241780970469630835">"ફક્ત એલાર્મ્સ"</string> <string name="quick_settings_dnd_none_label" msgid="8420869988472836354">"સાવ શાંતિ"</string> <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"બ્લૂટૂથ"</string> - <string name="quick_settings_bluetooth_multiple_devices_label" msgid="6595808498429809855">"બ્લૂટૂથ (<xliff:g id="NUMBER">%d</xliff:g> ઉપકરણો)"</string> + <string name="quick_settings_bluetooth_multiple_devices_label" msgid="6595808498429809855">"બ્લૂટૂથ (<xliff:g id="NUMBER">%d</xliff:g> ડિવાઇસ)"</string> <string name="quick_settings_bluetooth_off_label" msgid="6375098046500790870">"બ્લૂટૂથ બંધ"</string> <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"કોઈ જોડી કરેલ ઉપકરણો ઉપલબ્ધ નથી"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> બૅટરી"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"બબલને કોઈપણ સમયે નિયંત્રિત કરો"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"આ ઍપમાંથી બબલને બંધ કરવા માટે મેનેજ કરો પર ટૅપ કરો"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"સમજાઈ ગયું"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> સેટિંગ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index af45c6805fb8..19799839e7a9 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -1001,8 +1001,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जब चाहें, बबल्स को कंट्रोल करें"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'प्रबंधित करें\' पर टैप करें"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ठीक है"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> की सेटिंग"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index b5e6474aa343..521ca575525e 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Buborékok vezérlése bármikor"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"A Kezelés gombra koppintva kapcsolhatja ki az alkalmazásból származó buborékokat"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Értem"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> beállításai"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Készenléti mód"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index f2ec4b9960ca..93f0001f625c 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -99,7 +99,7 @@ <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Սարքի բարձրախոսը և խոսափողը"</string> <string name="screenrecord_start" msgid="330991441575775004">"Սկսել"</string> <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Էկրանի տեսագրում"</string> - <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Էկրանի տեսագրում և աուդիո ձայնագրում"</string> + <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Էկրանի տեսագրում և ձայնագրում"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Ցուցադրել էկրանի հպումները"</string> <string name="screenrecord_stop_text" msgid="6549288689506057686">"Հպեք՝ դադարեցնելու համար"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Կանգնեցնել"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ամպիկների կարգավորումներ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Հպեք «Կառավարել» կոճակին՝ այս հավելվածի ամպիկներն անջատելու համար։"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Եղավ"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – կարգավորումներ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index f9126db5f131..ac011a3dfc8f 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -192,7 +192,7 @@ <string name="accessibility_data_two_bars" msgid="4576231688545173059">"Data dua batang."</string> <string name="accessibility_data_three_bars" msgid="3036562180893930325">"Data tiga batang."</string> <string name="accessibility_data_signal_full" msgid="283507058258113551">"Sinyal data penuh."</string> - <string name="accessibility_wifi_name" msgid="4863440268606851734">"Tersambung ke <xliff:g id="WIFI">%s</xliff:g>."</string> + <string name="accessibility_wifi_name" msgid="4863440268606851734">"Terhubung ke <xliff:g id="WIFI">%s</xliff:g>."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Tersambung ke <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Terhubung ke <xliff:g id="CAST">%s</xliff:g>."</string> <string name="accessibility_no_wimax" msgid="2014864207473859228">"Tidak ada WiMAX."</string> @@ -203,7 +203,7 @@ <string name="accessibility_ethernet_disconnected" msgid="2097190491174968655">"Ethernet terputus."</string> <string name="accessibility_ethernet_connected" msgid="3988347636883115213">"Ethernet tersambung."</string> <string name="accessibility_no_signal" msgid="1115622734914921920">"Tidak ada sinyal."</string> - <string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak tersambung."</string> + <string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak terhubung."</string> <string name="accessibility_zero_bars" msgid="1364823964848784827">"0 baris."</string> <string name="accessibility_one_bar" msgid="6312250030039240665">"Satu garis."</string> <string name="accessibility_two_bars" msgid="1335676987274417121">"Dua baris."</string> @@ -373,7 +373,7 @@ <string name="quick_settings_user_title" msgid="8673045967216204537">"Pengguna"</string> <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Pengguna baru"</string> <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string> - <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Tidak Tersambung"</string> + <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Tidak Terhubung"</string> <string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Tidak Ada Jaringan"</string> <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi Mati"</string> <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi Aktif"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index e8e5b7af7b90..0a5c8faee1cd 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Hægt er að stjórna blöðrum hvenær sem er"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ýttu á „Stjórna“ til að slökkva á blöðrum frá þessu forriti"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ég skil"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Stillingar <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Biðstaða"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index c4b167bff07a..fab1eab2a9e2 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -91,7 +91,7 @@ <string name="screenrecord_name" msgid="2596401223859996572">"Registrazione dello schermo"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Avviare la registrazione?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"Durante la registrazione, il sistema Android può catturare dati sensibili visibili sullo schermo o riprodotti sul tuo dispositivo. Sono incluse password, dati di pagamento, foto, messaggi e audio."</string> + <string name="screenrecord_description" msgid="1123231719680353736">"Durante la registrazione, il sistema Android può acquisire dati sensibili visibili sullo schermo o riprodotti sul tuo dispositivo, tra cui password, dati di pagamento, foto, messaggi e audio."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Registra audio"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio del dispositivo"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Suoni del dispositivo, come musica, chiamate e suonerie"</string> @@ -373,7 +373,7 @@ <string name="quick_settings_user_title" msgid="8673045967216204537">"Utente"</string> <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Nuovo utente"</string> <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string> - <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non connesso"</string> + <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Non connessa"</string> <string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Nessuna rete"</string> <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi disattivato"</string> <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi attivo"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 894bb03cacb0..09b53b51f574 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -1009,8 +1009,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"שליטה בבועות, בכל זמן"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"יש להקיש על \'ניהול\' כדי להשבית את הבועות מהאפליקציה הזו"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"הבנתי"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"הגדרות <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 82f77530f1ab..b8e0ef5227fd 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Қалқыма хабарларды реттеу"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бұл қолданбадан қалқыма хабарларды өшіру үшін \"Басқару\" түймесін түртіңіз."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түсінікті"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> параметрлері"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index aa1d77660cc1..ebe3659bd09e 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"គ្រប់គ្រងពពុះបានគ្រប់ពេល"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ចុច \"គ្រប់គ្រង\" ដើម្បីបិទពពុះពីកម្មវិធីនេះ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"យល់ហើយ"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"ការកំណត់ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"បានធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅកាន់ការកំណត់។"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ចូលទៅកាន់ការកំណត់ ដើម្បីធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ផ្អាកដំណើរការ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 6fb7a1f648f9..9b411daec4ea 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಬಬಲ್ಸ್ ಅನ್ನು ನಿಯಂತ್ರಿಸಿ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ಈ ಆ್ಯಪ್ನಿಂದ ಬಬಲ್ಸ್ ಅನ್ನು ಆಫ್ ಮಾಡಲು ನಿರ್ವಹಿಸಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ಅರ್ಥವಾಯಿತು"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ಸ್ಟ್ಯಾಂಡ್ಬೈ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index f8e6b1f54066..38ae28d61cf3 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"언제든지 대화창을 제어하세요"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"이 앱에서 대화창을 사용 중지하려면 관리를 탭하세요."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"확인"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> 설정"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string> diff --git a/packages/SystemUI/res/values-ky-ldrtl/strings.xml b/packages/SystemUI/res/values-ky-ldrtl/strings.xml index b01a195dae38..2bc0fe45895a 100644 --- a/packages/SystemUI/res/values-ky-ldrtl/strings.xml +++ b/packages/SystemUI/res/values-ky-ldrtl/strings.xml @@ -19,5 +19,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Колдонмолорду тез которуштуруу үчүн солго сүйрөңүз"</string> + <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Колдонмолорду тез которуштуруу үчүн, солго сүйрөңүз"</string> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index ae6c50adf7bd..0e422d4778b8 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -36,7 +36,7 @@ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Батареяны үнөмдөө режимин күйгүзөсүзбү?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Батареяны үнөмдөгүч режими жөнүндө маалымат"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Күйгүзүү"</string> - <string name="battery_saver_start_action" msgid="4553256017945469937">"Батареяны үнөмдөгүч режимин күйгүзүү"</string> + <string name="battery_saver_start_action" msgid="4553256017945469937">"Батареяны үнөмдөгүчтү күйгүзүү"</string> <string name="status_bar_settings_settings_button" msgid="534331565185171556">"Жөндөөлөр"</string> <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi‑Fi"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Экранды авто буруу"</string> @@ -90,8 +90,8 @@ <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string> <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string> - <string name="screenrecord_start_label" msgid="1750350278888217473">"Жаздырып башталсынбы?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"Жаздыруу учурунда Android тутуму экраныңызда көрүнүп турган жана түзмөктө ойнотулуп жаткан бардык купуя маалыматты жаздырып алат. Буга сырсөздөр, төлөм маалыматы, сүрөттөр, билдирүүлөр жана аудио файлдар кирет."</string> + <string name="screenrecord_start_label" msgid="1750350278888217473">"Жаздырып баштайсызбы?"</string> + <string name="screenrecord_description" msgid="1123231719680353736">"Жаздыруу учурунда Android тутуму экраныңызда көрүнүп турган жана түзмөктө ойноп жаткан бардык купуя маалыматты жаздырып алат. Буга сырсөздөр, төлөм маалыматы, сүрөттөр, билдирүүлөр жана аудио файлдар кирет."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жаздыруу"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Түзмөктүн аудиосу"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Музыка, чалуулар жана рингтондор сыяктуу түзмөгүңүздөгү добуштар"</string> @@ -101,7 +101,7 @@ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Экран жаздырылууда"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Экран жана аудио жаздырылууда"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Экранды басууларды көрсөтүү"</string> - <string name="screenrecord_stop_text" msgid="6549288689506057686">"Токтотуш үчүн басыңыз"</string> + <string name="screenrecord_stop_text" msgid="6549288689506057686">"Токтотуу үчүн басып коюңуз"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Токтотуу"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"Тындыруу"</string> <string name="screenrecord_resume_label" msgid="4972223043729555575">"Улантуу"</string> @@ -373,7 +373,7 @@ <string name="quick_settings_user_title" msgid="8673045967216204537">"Колдонуучу"</string> <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Жаңы колдонуучу"</string> <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string> - <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Интернет жок"</string> + <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Туташкан жок"</string> <string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Желе жок"</string> <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi өчүк"</string> <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi күйүк"</string> @@ -498,7 +498,7 @@ <string name="user_remove_user_remove" msgid="8387386066949061256">"Алып салуу"</string> <string name="battery_saver_notification_title" msgid="8419266546034372562">"Батареяны үнөмдөгүч режими күйүк"</string> <string name="battery_saver_notification_text" msgid="2617841636449016951">"Иштин майнаптуулугун начарлатып, фондук дайын-даректерди чектейт"</string> - <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Батареяны үнөмдөгүч режимин өчүрүү"</string> + <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Батареяны үнөмдөгүчтү өчүрүү"</string> <string name="media_projection_dialog_text" msgid="1755705274910034772">"Бул функцияны аткарган <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> кызматы экраныңызда көрүнүп турган бардык маалыматты же жаздыруу жана тышкы экранга чыгаруу учурунда түзмөгүңүздө ойнотулган маалыматты колдоно алат. Буга сырсөздөр, төлөмдүн чоо-жайы, сүрөттөр, билдирүүлөр жана ойнотулган аудио кирет."</string> <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Бул функцияны аткарган кызматка экраныңыздагы бардык маалымат же түзмөктө ойнотулуп жаткан нерсе, сырсөздөр, төлөмдөрдүн чоо-жайы, сүрөттөр, билдирүүлөр жана аудио файлдар жеткиликтүү болот."</string> <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жаздырып же тышкы экранга чыгарып баштайсызбы?"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн \"Башкарууну\" басыңыз"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түшүндүм"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> жөндөөлөрү"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 7374acd07afc..17be731c06c6 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -1009,8 +1009,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bet kada valdyti burbulus"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Palieskite „Tvarkyti“, kad išjungtumėte burbulus šioje programoje"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Supratau"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ nustatymai"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Budėjimo laikas"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 2ace26779b95..f402323deac3 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -1004,8 +1004,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Pārvaldīt burbuļus jebkurā laikā"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Pieskarieties pogai “Pārvaldīt”, lai izslēgtu burbuļus no šīs lietotnes."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Labi"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Lietotnes <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iestatījumi"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gaidstāve"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 67392bb14d52..03af224a320b 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -91,7 +91,7 @@ <string name="screenrecord_name" msgid="2596401223859996572">"Снимач на екран"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Да се започне со снимање?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"При снимањето, системот на Android може да ги сними сите чувствителни податоци што се видливи на вашиот екран или пуштени на уредот. Ова вклучува лозинки, податоци за плаќање, фотографии, пораки и аудио."</string> + <string name="screenrecord_description" msgid="1123231719680353736">"При снимањето, системот Android може да ги сними сите чувствителни податоци што се видливи на вашиот екран или пуштени на уредот. Ова вклучува лозинки, податоци за плаќање, фотографии, пораки и аудио."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Снимај аудио"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Аудио од уредот"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук од вашиот уред, како на пр., музика, повици и мелодии"</string> @@ -211,7 +211,7 @@ <string name="accessibility_signal_full" msgid="5920148525598637311">"Полн сигнал."</string> <string name="accessibility_desc_on" msgid="2899626845061427845">"Вклучена."</string> <string name="accessibility_desc_off" msgid="8055389500285421408">"Исклучено."</string> - <string name="accessibility_desc_connected" msgid="3082590384032624233">"Поврзана."</string> + <string name="accessibility_desc_connected" msgid="3082590384032624233">"Поврзано."</string> <string name="accessibility_desc_connecting" msgid="8011433412112903614">"Се поврзува."</string> <string name="data_connection_gprs" msgid="2752584037409568435">"GPRS"</string> <string name="data_connection_hspa" msgid="6096234094857660873">"HSPA"</string> @@ -416,7 +416,7 @@ <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Ноќно светло"</string> <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Вклуч. на зајдисонце"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"До изгрејсонце"</string> - <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Ќе се вклучи во <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Вклучување: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"До <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Темна тема"</string> <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Штедач на батерија"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролирајте ги балончињата во секое време"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Допрете „Управувајте“ за да ги исклучите балончињата од апликацијава"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Сфатив"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Поставки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 44a2aa11bbc2..d7e6b3b687ad 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ബബിളുകൾ ഏതുസമയത്തും നിയന്ത്രിക്കുക"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ഈ ആപ്പിൽ നിന്നുള്ള ബബിളുകൾ ഓഫാക്കാൻ മാനേജ് ചെയ്യുക ടാപ്പ് ചെയ്യുക"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ലഭിച്ചു"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ക്രമീകരണം"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"സ്റ്റാൻഡ്ബൈ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"സംഭാഷണ വിഭാഗത്തിന്റെ മുകളിൽ കാണിക്കുക"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ലോക്ക് സ്ക്രീനിൽ പ്രൊഫൈൽ ചിത്രം കാണിക്കുക"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ആപ്പുകളുടെ മുകളിൽ ഫ്ലോട്ടിംഗ് ബബിൾ ആയി ദൃശ്യമാകും"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ശല്യപ്പെടുത്തരുത്\' തടസ്സപ്പെടുത്തുക"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"മനസ്സിലായി"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"മാഗ്നിഫിക്കേഷൻ ഓവർലേ വിൻഡോ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ നിയന്ത്രണങ്ങൾ"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 0f17270ac3cc..1e646bc1ac4a 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -36,7 +36,7 @@ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Батарей хэмнэгчийг асаах уу?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Батарей хэмнэгчийн тухай"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Асаах"</string> - <string name="battery_saver_start_action" msgid="4553256017945469937">"Тэжээл хэмнэгчийг асаах"</string> + <string name="battery_saver_start_action" msgid="4553256017945469937">"Батарей хэмнэгчийг асаах"</string> <string name="status_bar_settings_settings_button" msgid="534331565185171556">"Тохиргоо"</string> <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Дэлгэцийг автоматаар эргүүлэх"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Дурын үед бөмбөлгийг хянаарай"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Энэ аппын бөмбөлгүүдийг унтраахын тулд Удирдах дээр товшино уу"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ойлголоо"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-н тохиргоо"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Зогсолтын горим"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 926b636439bc..af8a52db49be 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"बबल कधीही नियंत्रित करा"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"या अॅपमधून बबल बंद करण्यासाठी व्यवस्थापित करा वर टॅप करा"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"समजले"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> सेटिंग्ज"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"संभाषण विभागाच्या सर्वात वरती दाखवा"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लॉक स्क्रीनवर प्रोफाइल फोटो दाखवा"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ॲप्सच्या सर्वात वरती फ्लोटिंग बबल म्हणून दिसतील"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"व्यत्यय आणू नका मध्ये अडथळा आणतील"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"समजले"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"मॅग्निफिकेशन ओव्हरले विंडो"</string> <string name="magnification_window_title" msgid="4863914360847258333">"मॅग्निफिकेशन विंडो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"मॅग्निफिकेशन विंडो नियंत्रणे"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index efd2c851e409..c1c35a1dbfcb 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kawal gelembung pada bila-bila masa"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ketik Urus untuk mematikan gelembung daripada apl ini"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Tetapan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tunggu sedia"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 5ee07ae4dfc4..088371e2449e 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollér bobler når som helst"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trykk på Administrer for å slå av bobler for denne appen"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Greit"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-innstillinger"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ventemodus"</string> diff --git a/packages/SystemUI/res/values-ne-ldrtl/strings.xml b/packages/SystemUI/res/values-ne-ldrtl/strings.xml index b154443ad78b..4594c55aa447 100644 --- a/packages/SystemUI/res/values-ne-ldrtl/strings.xml +++ b/packages/SystemUI/res/values-ne-ldrtl/strings.xml @@ -19,5 +19,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"अनुप्रयोगहरू द्रुत गतिमा बदल्न बायाँतिर ड्र्याग गर्नुहोस्"</string> + <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"एपहरू द्रुत गतिमा बदल्न बायाँतिर ड्र्याग गर्नुहोस्"</string> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index ec7efdbc2b25..04cdeaf7685c 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -52,7 +52,7 @@ <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string> <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> सञ्चालन गर्न खोल्ने हो?\nयो अनुप्रयोगलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string> <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string> - <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"यस USB उपकरणसँग स्थापित अनुप्रयोग काम गर्दैन। यस उपकरणको बारेमा <xliff:g id="URL">%1$s</xliff:g> मा धेरै जान्नुहोस्"</string> + <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"यस USB उपकरणसँग स्थापित एप काम गर्दैन। यस उपकरणको बारेमा <xliff:g id="URL">%1$s</xliff:g> मा धेरै जान्नुहोस्"</string> <string name="title_usb_accessory" msgid="1236358027511638648">"USB सहयोगी"</string> <string name="label_view" msgid="6815442985276363364">"दृश्य"</string> <string name="always_use_device" msgid="210535878779644679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> जडान भएको बेला सधैँ <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्नुहोस्"</string> @@ -85,14 +85,13 @@ <string name="screenshot_failed_title" msgid="3259148215671936891">"स्क्रिनसट सुरक्षित गर्न सकिएन"</string> <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रिनसट फेरि लिएर हेर्नुहोस्"</string> <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"भण्डारण ठाउँ सीमित भएका कारण स्क्रिनसट सुरक्षित गर्न सकिएन"</string> - <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"उक्त अनुप्रयोग वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string> + <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"उक्त एप वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रिनसट हटाउनुहोस्"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रिनसटको पूर्वावलोकन"</string> <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"रेकर्ड गर्न थाल्ने हो?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"रेकर्ड गर्दा, Android प्रणालीले तपाईंको स्क्रिनमा देखिने वा तपाईंको यन्त्रमा प्ले गरिने जुनसुकै संवेदनशील जानकारी समावेश गर्न सक्छ। यसमा पासवर्ड, भुक्तानीसम्बन्धी जानकारी, फोटो, सन्देश र अडियो समावेश हुन्छ।"</string> + <string name="screenrecord_description" msgid="1123231719680353736">"रेकर्ड गर्दा, Android प्रणालीले तपाईंको स्क्रिनमा देखिने वा तपाईंको यन्त्रमा प्ले गरिने सबै संवेदनशील जानकारी रेकर्ड गर्न सक्छ। यो जानकारीमा पासवर्ड, भुक्तानीसम्बन्धी जानकारी, फोटो, सन्देश र अडियो समावेश हुन्छ।"</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"अडियो रेकर्ड गर्नुहोस्"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"यन्त्रको अडियो"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"तपाईंको यन्त्रका सङ्गीत, कल र रिङटोन जस्ता आवाज"</string> @@ -101,13 +100,13 @@ <string name="screenrecord_start" msgid="330991441575775004">"सुरु गर्नुहोस्"</string> <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रिन रेकर्ड गर्दै"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"स्क्रिन र अडियो रेकर्ड गर्दै"</string> - <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रिन रेकर्ड गर्ने क्रममा स्पर्श गरिएका स्थानहरू देखाउनुहोस्"</string> + <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्पर्श गरिएका स्थानहरू देखाउनुहोस्"</string> <string name="screenrecord_stop_text" msgid="6549288689506057686">"रोक्न ट्याप गर्नुहोस्"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"रोक्नुहोस्"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"पज गर्नुहोस्"</string> <string name="screenrecord_resume_label" msgid="4972223043729555575">"जारी राख्नुहोस्"</string> <string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द गर्नुहोस्"</string> - <string name="screenrecord_share_label" msgid="5025590804030086930">"आदान प्रदान गर्नुहोस्"</string> + <string name="screenrecord_share_label" msgid="5025590804030086930">"सेयर गर्नुहोस्"</string> <string name="screenrecord_delete_label" msgid="1376347010553987058">"मेट्नुहोस्"</string> <string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रिन रेकर्ड गर्ने कार्य रद्द गरियो"</string> <string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रिन रेकर्डिङ सुरक्षित गरियो, हेर्न ट्याप गर्नुहोस्"</string> @@ -118,7 +117,7 @@ <string name="usb_preference_title" msgid="1439924437558480718">"USB फाइल सार्ने विकल्पहरू"</string> <string name="use_mtp_button_title" msgid="5036082897886518086">"मिडिया प्लेयर(MTP)को रूपमा माउन्ट गर्नुहोस्"</string> <string name="use_ptp_button_title" msgid="7676427598943446826">"क्यामेराको रूपमा माउन्ट गर्नुहोस् (PTP)"</string> - <string name="installer_cd_button_title" msgid="5499998592841984743">"म्याकको लागि एन्ड्रोइड फाइल ट्रान्सफर अनुप्रयोग स्थापना गर्नुहोस्"</string> + <string name="installer_cd_button_title" msgid="5499998592841984743">"म्याकको लागि एन्ड्रोइड फाइल ट्रान्सफर एप स्थापना गर्नुहोस्"</string> <string name="accessibility_back" msgid="6530104400086152611">"पछाडि"</string> <string name="accessibility_home" msgid="5430449841237966217">"गृह"</string> <string name="accessibility_menu" msgid="2701163794470513040">"मेनु"</string> @@ -356,7 +355,7 @@ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"श्रवण यन्त्रहरू"</string> <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सक्रिय गर्दै…"</string> <string name="quick_settings_brightness_label" msgid="680259653088849563">"चमक"</string> - <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"स्वतःघुम्ने"</string> + <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अटो रोटेट"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रिन स्वतःघुम्ने"</string> <string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> मोड"</string> <string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"परिक्रमण लक गरिएको छ"</string> @@ -431,8 +430,8 @@ <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"स्रिनको रेकर्ड"</string> <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"सुरु गर्नुहोस्"</string> <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"रोक्नुहोस्"</string> - <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"अनुप्रयोगहरू बदल्न माथितिर स्वाइप गर्नुहोस्"</string> - <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"अनुप्रयोगहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string> + <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"एपहरू बदल्न माथितिर स्वाइप गर्नुहोस्"</string> + <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"एपहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string> <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"परिदृश्य टगल गर्नुहोस्"</string> <string name="expanded_header_battery_charged" msgid="5307907517976548448">"चार्ज भयो"</string> <string name="expanded_header_battery_charging" msgid="1717522253171025549">"चार्ज हुँदै"</string> @@ -475,27 +474,27 @@ <string name="user_add_user" msgid="4336657383006913022">"प्रयोगकर्ता थप्नुहोस्"</string> <string name="user_new_user_name" msgid="2019166282704195789">"नयाँ प्रयोगकर्ता"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि हटाउने हो?"</string> - <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यस सत्रमा सबै अनुप्रयोगहरू र डेटा मेटाइनेछ।"</string> + <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यस सत्रमा सबै एपहरू र डेटा मेटाइनेछ।"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"पुनः स्वागत, अतिथि!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string> <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string> <string name="guest_notification_title" msgid="4434456703930764167">"अतिथि प्रयोगकर्ता"</string> - <string name="guest_notification_text" msgid="4202692942089571351">"अनुप्रयोगहरू र डेटा मेटाउन, अतिथि प्रयोगकर्ता हटाउनुहोस्"</string> + <string name="guest_notification_text" msgid="4202692942089571351">"एपहरू र डेटा मेटाउन, अतिथि प्रयोगकर्ता हटाउनुहोस्"</string> <string name="guest_notification_remove_action" msgid="4153019027696868099">"अतिथिलाई हटाउनुहोस्"</string> <string name="user_logout_notification_title" msgid="3644848998053832589">"प्रयोगकर्ता लगआउट गर्नुहोस्"</string> <string name="user_logout_notification_text" msgid="7441286737342997991">"वर्तमान प्रयोगकर्ता लगआउट गर्नुहोस्"</string> <string name="user_logout_notification_action" msgid="7974458760719361881">"प्रयोगकर्ता लगआउट गर्नुहोस्"</string> <string name="user_add_user_title" msgid="4172327541504825032">"नयाँ प्रयोगकर्ता थप्ने हो?"</string> - <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nकुनै पनि प्रयोगकर्ताले सबै अन्य प्रयोगकर्ताहरूका लागि अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string> + <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nकुनै पनि प्रयोगकर्ताले सबै अन्य प्रयोगकर्ताहरूका लागि एपहरू अद्यावधिक गर्न सक्छन्।"</string> <string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string> <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398"> <item quantity="other">तपाईं अधिकतम <xliff:g id="COUNT">%d</xliff:g> प्रयोगहरू मात्र थप्न सक्नुहुन्छ।</item> <item quantity="one">एउटा प्रयोगकर्ता मात्र सिर्जना गर्न सकिन्छ।</item> </plurals> <string name="user_remove_user_title" msgid="9124124694835811874">"प्रयोगकर्ता हटाउन चाहनुहुन्छ?"</string> - <string name="user_remove_user_message" msgid="6702834122128031833">"यस प्रयोगकर्ताको सबै अनुप्रयोगहरू तथा डेटा हटाइने छ।"</string> + <string name="user_remove_user_message" msgid="6702834122128031833">"यस प्रयोगकर्ताको सबै एपहरू तथा डेटा हटाइने छ।"</string> <string name="user_remove_user_remove" msgid="8387386066949061256">"हटाउनुहोस्"</string> <string name="battery_saver_notification_title" msgid="8419266546034372562">"ब्याट्री सेभर सक्रिय छ"</string> <string name="battery_saver_notification_text" msgid="2617841636449016951">"प्रदर्शन र पृष्ठभूमि डेटा घटाउँनुहोस्"</string> @@ -542,35 +541,35 @@ <string name="disable_vpn" msgid="482685974985502922">"VPN असक्षम गर्नुहोस्"</string> <string name="disconnect_vpn" msgid="26286850045344557">"विच्छेद VPN"</string> <string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतिहरू हेर्नुहोस्"</string> - <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले तपाईंको यन्त्रको व्यवस्थापन गर्छ।BREAK\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, अनुप्रयोगहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> - <string name="monitoring_description_management" msgid="8081910434889677718">"तपाईंको संगठनले तपाईंको यन्त्रको व्यवस्थापन गर्छ।\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, अनुप्रयोगहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> + <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले तपाईंको यन्त्रको व्यवस्थापन गर्छ।BREAK\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, एपहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> + <string name="monitoring_description_management" msgid="8081910434889677718">"तपाईंको संगठनले तपाईंको यन्त्रको व्यवस्थापन गर्छ।\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, एपहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापित गऱ्यो। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string> <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरेको छ। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"यस यन्त्रमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरिएको छ। तपाईंको सुरक्षित नेटवर्कको ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"तपाईंका प्रशासकले तपाईंको यन्त्रमा ट्राफिकको अनुगमन गर्ने नेटवर्क लग गर्ने प्रक्रियालाई सक्रिय गर्नुभएको छ।"</string> - <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"तपाईं इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string> - <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"तपाईं इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP_0">%1$s</xliff:g> र <xliff:g id="VPN_APP_1">%2$s</xliff:g> मा जडान हुनुहुन्छ।"</string> - <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"तपाईंको कार्य प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string> - <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"तपाईंको व्यक्तिगत प्रोफाइल इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string> + <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"तपाईं इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string> + <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"तपाईं इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP_0">%1$s</xliff:g> र <xliff:g id="VPN_APP_1">%2$s</xliff:g> मा जडान हुनुहुन्छ।"</string> + <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"तपाईंको कार्य प्रोफाइल तपाईंका इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string> + <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"तपाईंको व्यक्तिगत प्रोफाइल इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string> <string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"तपाईंको यन्त्र <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> द्वारा व्यवस्थापन गरिएको छ।"</string> <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले तपाईंको यन्त्रको व्यवस्थापन गर्न <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> को प्रयोग गर्दछ।"</string> - <string name="monitoring_description_do_body" msgid="7700878065625769970">"तपाईँको प्रशासकले सेटिङहरू, संस्थागत पहुँच, अनुप्रयोग, तपाईँको यन्त्रसँग सम्बन्धित डेटा र तपाईँको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।"</string> + <string name="monitoring_description_do_body" msgid="7700878065625769970">"तपाईँको प्रशासकले सेटिङहरू, संस्थागत पहुँच, एप, तपाईँको यन्त्रसँग सम्बन्धित डेटा र तपाईँको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।"</string> <string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string> <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"थप जान्नुहोस्"</string> - <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"तपाईं <xliff:g id="VPN_APP">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, अनुप्रयोग र वेबसाइटहरू लगायत तपाईंको नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string> + <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"तपाईं <xliff:g id="VPN_APP">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string> <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN सम्बन्धी सेटिङहरू खोल्नुहोस्"</string> <string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string> <string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"खुला विश्वसनीय प्रमाणहरू"</string> <string name="monitoring_description_network_logging" msgid="577305979174002252">"तपाईँको प्रशासकले तपाईँको यन्त्रमा ट्राफिकको अनुगमन गर्ने नेटवर्कको लगिङलाई सक्रिय पार्नुभएको छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> - <string name="monitoring_description_vpn" msgid="1685428000684586870">"तपाईँले VPN जडान गर्न अनुप्रयोगलाई अनुमति दिनुभयो।\n\nयो अनुप्रयोगले तपाईँका यन्त्र र नेटवर्क गतिविधि लगायत इमेल, अनुप्रयोग र वेबसाइटहरू अनुगमन गर्न सक्छ।"</string> - <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"तपाईंको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> ले व्यवस्थापन गर्दछ।\n\nतपाईंको प्रशासकले तपाईंको इमेल, अनुप्रयोग र वेबसाइट सहित नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्नुहुन्छ। \n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।\n\n तपाईं एउटा VPN मा जडित हुनुहुन्छ। यस VPN ले नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्छ।"</string> + <string name="monitoring_description_vpn" msgid="1685428000684586870">"तपाईँले VPN जडान गर्न एपलाई अनुमति दिनुभयो।\n\nयो एपले तपाईँका यन्त्र र नेटवर्क गतिविधि लगायत इमेल, एप र वेबसाइटहरू अनुगमन गर्न सक्छ।"</string> + <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"तपाईंको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> ले व्यवस्थापन गर्दछ।\n\nतपाईंको प्रशासकले तपाईंको इमेल, एप र वेबसाइट सहित नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्नुहुन्छ। \n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।\n\n तपाईं एउटा VPN मा जडित हुनुहुन्छ। यस VPN ले नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्छ।"</string> <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string> - <string name="monitoring_description_app" msgid="376868879287922929">"तपाईं आफ्ना इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string> - <string name="monitoring_description_app_personal" msgid="1970094872688265987">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> सँग जडित हुनुहुन्छ जसले इ-मेल, अनुप्रयोगहरू र वेबसाइट लगायतका तपाईंको निजी नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।"</string> - <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, अनुप्रयोग र वेबसाइटहरू लगायतको तपाईंको व्यक्तिगत नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string> - <string name="monitoring_description_app_work" msgid="3713084153786663662">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%2$s</xliff:g> मा जडान छ।\n\nथप जानकारीका लागि, आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> - <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> मा जडान छ। \n\nतपाईं आफ्नो व्यक्तिगत नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> मा पनि जडान हुनुहुन्छ।"</string> + <string name="monitoring_description_app" msgid="376868879287922929">"तपाईं आफ्ना इमेल, एप र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string> + <string name="monitoring_description_app_personal" msgid="1970094872688265987">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> सँग जडित हुनुहुन्छ जसले इ-मेल, एपहरू र वेबसाइट लगायतका तपाईंको निजी नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।"</string> + <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, एप र वेबसाइटहरू लगायतको तपाईंको व्यक्तिगत नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string> + <string name="monitoring_description_app_work" msgid="3713084153786663662">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, एप र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%2$s</xliff:g> मा जडान छ।\n\nथप जानकारीका लागि, आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> + <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, एप र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> मा जडान छ। \n\nतपाईं आफ्नो व्यक्तिगत नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> मा पनि जडान हुनुहुन्छ।"</string> <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ले खुला राखेको"</string> <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"तपाईँले नखोले सम्म उपकरण बन्द रहनेछ"</string> <string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string> @@ -639,7 +638,7 @@ <string name="output_service_bt_wifi" msgid="7186882540475524124">"ब्लुटुथ र Wi-Fi"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"प्रणाली UI ट्युनर"</string> <string name="show_battery_percentage" msgid="6235377891802910455">"इम्बेड गरिएको ब्याट्री प्रतिशत देखाउनुहोस्"</string> - <string name="show_battery_percentage_summary" msgid="9053024758304102915">"चार्ज नगरेको बेला वस्तुस्थिति पट्टी आइकन भित्र ब्याट्री प्रतिशत स्तर देखाउनुहोस्"</string> + <string name="show_battery_percentage_summary" msgid="9053024758304102915">"चार्ज नगरेको बेला स्टाटस बार आइकन भित्र ब्याट्री प्रतिशत स्तर देखाउनुहोस्"</string> <string name="quick_settings" msgid="6211774484997470203">"द्रुत सेटिङहरू"</string> <string name="status_bar" msgid="4357390266055077437">"स्थिति पट्टी"</string> <string name="overview" msgid="3522318590458536816">"परिदृश्य"</string> @@ -666,7 +665,7 @@ <string name="tuner_toast" msgid="3812684836514766951">"बधाईँ छ! सेटिङहरूमा प्रणाली UI ट्युनर थप गरिएको छ"</string> <string name="remove_from_settings" msgid="633775561782209994">"सेटिङहरूबाट हटाउनुहोस्"</string> <string name="remove_from_settings_prompt" msgid="551565437265615426">"प्रणाली UI ट्युनर सेटिङहरूबाट हटाउने र यसका सबै सुविधाहरू प्रयोग गर्न रोक्ने हो?"</string> - <string name="activity_not_found" msgid="8711661533828200293">"तपाईँको यन्त्रमा अनुप्रयोग स्थापना भएको छैन"</string> + <string name="activity_not_found" msgid="8711661533828200293">"तपाईँको यन्त्रमा एप स्थापना भएको छैन"</string> <string name="clock_seconds" msgid="8709189470828542071">"घडीमा सेकेन्ड देखाउनुहोस्"</string> <string name="clock_seconds_desc" msgid="2415312788902144817">"वस्तुस्थिति पट्टीको घडीमा सेकेन्ड देखाउनुहोस्। ब्याट्री आयु प्रभावित हुन सक्छ।"</string> <string name="qs_rearrange" msgid="484816665478662911">"द्रुत सेटिङहरू पुनः व्यवस्थित गर्नुहोस्"</string> @@ -796,7 +795,7 @@ <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"सूचनाहरू"</string> <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"किबोर्ड सर्टकटहरू"</string> <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"किबोर्डको लेआउट बदल्नुहोस्"</string> - <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"अनुप्रयोगहरू"</string> + <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"एपहरू"</string> <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"सहायता"</string> <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ब्राउजर"</string> <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"सम्पर्कहरू"</string> @@ -915,7 +914,7 @@ <string name="pip_skip_to_prev" msgid="3742589641443049237">"अघिल्लोमा जानुहोस्"</string> <string name="thermal_shutdown_title" msgid="2702966892682930264">"फोन अति नै तातिएकाले चिसिन बन्द भयो"</string> <string name="thermal_shutdown_message" msgid="7432744214105003895">"तपाईंको फोन अब सामान्य ढंगले चल्दै छ"</string> - <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n • धेरै संसाधन खपत गर्ने अनुप्रयोगहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन अनुप्रयोगहरू)\n • ठूला फाइलहरूको डाउनलोड वा अपलोड\n • उच्च तापक्रममा फोनको प्रयोग"</string> + <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n • धेरै संसाधन खपत गर्ने एपहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन एपहरू)\n • ठूला फाइलहरूको डाउनलोड वा अपलोड\n • उच्च तापक्रममा फोनको प्रयोग"</string> <string name="high_temp_title" msgid="2218333576838496100">"फोन तातो भइरहेको छ"</string> <string name="high_temp_notif_message" msgid="163928048626045592">"फोन चिसो हुँदै गर्दा केही विशेषताहरूलाई सीमित गरिन्छ"</string> <string name="high_temp_dialog_message" msgid="3793606072661253968">"तपाईंको फोन स्वतः चिसो हुने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो फोनको प्रयोग गर्न सक्नुहुन्छ तर त्यो अझ ढिलो चल्न सक्छ।\n\nचिसो भएपछि तपाईंको फोन सामान्य गतिमा चल्नेछ।"</string> @@ -928,24 +927,24 @@ <string name="lockscreen_unlock_right" msgid="4658008735541075346">"दायाँतिरको सर्टकटले पनि अनलक गर्छ"</string> <string name="lockscreen_none" msgid="4710862479308909198">"कुनै पनि होइन"</string> <string name="tuner_launch_app" msgid="3906265365971743305">"<xliff:g id="APP">%1$s</xliff:g> सुरु गर्नुहोस्"</string> - <string name="tuner_other_apps" msgid="7767462881742291204">"अन्य अनुप्रयोगहरू"</string> + <string name="tuner_other_apps" msgid="7767462881742291204">"अन्य एपहरू"</string> <string name="tuner_circle" msgid="5270591778160525693">"सर्कल"</string> <string name="tuner_plus" msgid="4130366441154416484">"प्लस चिन्ह"</string> <string name="tuner_minus" msgid="5258518368944598545">"माइनस चिन्ह"</string> <string name="tuner_left" msgid="5758862558405684490">"बायाँ"</string> <string name="tuner_right" msgid="8247571132790812149">"दायाँ"</string> <string name="tuner_menu" msgid="363690665924769420">"मेनु"</string> - <string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g> अनुप्रयोग"</string> + <string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g> एप"</string> <string name="notification_channel_alerts" msgid="3385787053375150046">"सतर्कताहरू"</string> <string name="notification_channel_battery" msgid="9219995638046695106">"ब्याट्री"</string> <string name="notification_channel_screenshot" msgid="7665814998932211997">"स्क्रिनशटहरू"</string> <string name="notification_channel_general" msgid="4384774889645929705">"सामान्य सन्देशहरू"</string> <string name="notification_channel_storage" msgid="2720725707628094977">"भण्डारण"</string> <string name="notification_channel_hints" msgid="7703783206000346876">"सङ्केतहरू"</string> - <string name="instant_apps" msgid="8337185853050247304">"तात्कालिक अनुप्रयोगहरू"</string> + <string name="instant_apps" msgid="8337185853050247304">"तात्कालिक एपहरू"</string> <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> चलिरहेको छ"</string> - <string name="instant_apps_message" msgid="6112428971833011754">"स्थापना नगरिकनै अनुप्रयोग खोलियो।"</string> - <string name="instant_apps_message_with_help" msgid="1816952263531203932">"स्थापना नगरिकनै अनुप्रयोग खोलियो। थप जान्न ट्याप गर्नुहोस्।"</string> + <string name="instant_apps_message" msgid="6112428971833011754">"स्थापना नगरिकनै एप खोलियो।"</string> + <string name="instant_apps_message_with_help" msgid="1816952263531203932">"स्थापना नगरिकनै एप खोलियो। थप जान्न ट्याप गर्नुहोस्।"</string> <string name="app_info" msgid="5153758994129963243">"एपसम्बन्धी जानकारी"</string> <string name="go_to_web" msgid="636673528981366511">"ब्राउजरमा जानुहोस्"</string> <string name="mobile_data" msgid="4564407557775397216">"मोबाइल डेटा"</string> @@ -960,7 +959,7 @@ <string name="qs_dnd_until" msgid="7844269319043747955">"<xliff:g id="ID_1">%s</xliff:g> सम्म"</string> <string name="qs_dnd_keep" msgid="3829697305432866434">"राख्नुहोस्"</string> <string name="qs_dnd_replace" msgid="7712119051407052689">"प्रतिस्थापन गर्नुहोस्"</string> - <string name="running_foreground_services_title" msgid="5137313173431186685">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string> + <string name="running_foreground_services_title" msgid="5137313173431186685">"पृष्ठभूमिमा चल्ने एपहरू"</string> <string name="running_foreground_services_msg" msgid="3009459259222695385">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string> <string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा निष्क्रिय पार्ने हो?"</string> <string name="mobile_data_disable_message" msgid="8604966027899770415">"तपाईं <xliff:g id="CARRIER">%s</xliff:g> मार्फत डेटा वा इन्टरनेट प्रयोग गर्न सक्नुहुने छैन। Wi-Fi मार्फत मात्र इन्टरनेट उपलब्ध हुने छ।"</string> @@ -983,7 +982,7 @@ <string name="sensor_privacy_mode" msgid="4462866919026513692">"सेन्सरहरू निष्क्रिय छन्"</string> <string name="device_services" msgid="1549944177856658705">"यन्त्रका सेवाहरू"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string> - <string name="restart_button_description" msgid="6916116576177456480">"यो अनुप्रयोग पुनः सुरु गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string> + <string name="restart_button_description" msgid="6916116576177456480">"यो एप पुनः सुरु गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string> <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> का बबलसम्बन्धी सेटिङहरू"</string> <string name="manage_bubbles_text" msgid="6856830436329494850">"व्यवस्थापन गर्नुहोस्"</string> <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> को <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> @@ -1000,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जुनसुकै बेला बबलहरू नियन्त्रण गर्नुहोस्"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"यो अनुप्रयोगबाट आएका बबलहरू निष्क्रिय पार्न व्यवस्थापन गर्नुहोस् नामक बटनमा ट्याप गर्नुहोस्"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"बुझेँ"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> का सेटिङहरू"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"वार्तालाप खण्डको सिरानमा देखाइयोस्"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल तस्बिर देखाइयोस्"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"एपहरूमाथि तैरिने बबलका रूपमा देखाइयोस्"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"बाधा नपुऱ्याउनुहोस् मोडलाई बेवास्ता गरियोस्"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"बुझेँ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"म्याग्निफिकेसन ओभरले विन्डो"</string> <string name="magnification_window_title" msgid="4863914360847258333">"म्याग्निफिकेसन विन्डो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"म्याग्निफिकेसन विन्डोका नियन्त्रणहरू"</string> @@ -1022,7 +1015,7 @@ <string name="quick_controls_subtitle" msgid="1667408093326318053">"आफ्ना जोडिएका यन्त्रहरूका लागि नियन्त्रण सुविधाहरू थप्नुहोस्"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"यन्त्र नियन्त्रण गर्ने विजेटहरू सेटअप गर्नुहोस्"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"आफ्ना नियन्त्रणहरूमाथि पहुँच राख्न पावर बटन थिचिराख्नुहोस्"</string> - <string name="controls_providers_title" msgid="6879775889857085056">"नियन्त्रणहरू थप्न अनुप्रयोग छनौट गर्नुहोस्"</string> + <string name="controls_providers_title" msgid="6879775889857085056">"नियन्त्रणहरू थप्न एप छनौट गर्नुहोस्"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> वटा नियन्त्र थपियो।</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> नियन्त्र थपियो</item> @@ -1047,7 +1040,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"थप हेर्न स्वाइप गर्नुहोस्"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"सिफारिसहरू लोड गर्दै"</string> <string name="controls_media_close_session" msgid="9023534788828414585">"यो मिडिया सत्र बन्द गर्नुहोस्"</string> - <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, अनुप्रयोग जाँच गर्नु…"</string> + <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string> <string name="controls_error_failed" msgid="960228639198558525">"त्रुटि भयो, फेरि प्रयास गर्नु…"</string> <string name="controls_in_progress" msgid="4421080500238215939">"कार्य हुँदै छ"</string> <string name="controls_added_tooltip" msgid="4842812921719153085">"नयाँ नियन्त्रण सुविधाहरू हेर्न पावर बटन थिचिराख्नुहोस्"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index cde084f3d27e..5c0679675ae7 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -32,12 +32,12 @@ <string name="invalid_charger" msgid="4370074072117767416">"USB ଦ୍ଵାରା ଚାର୍ଜ କରିହେବନାହିଁ। ଆପଣଙ୍କ ଡିଭାଇସ୍ ପାଇଁ ଥିବା ଚାର୍ଜର୍କୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string> <string name="invalid_charger_title" msgid="938685362320735167">"USB ଦ୍ଵାରା ଚାର୍ଜ କରିହେବନାହିଁ"</string> <string name="invalid_charger_text" msgid="2339310107232691577">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ପାଇଁ ଥିବା ଚାର୍ଜର୍କୁ ବ୍ୟବହାର କରନ୍ତୁ"</string> - <string name="battery_low_why" msgid="2056750982959359863">"ସେଟିଙ୍ଗ"</string> + <string name="battery_low_why" msgid="2056750982959359863">"ସେଟିଂସ୍"</string> <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"ବ୍ୟାଟେରୀ ସେଭର୍ ଚାଲୁ କରିବେ?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"ବ୍ୟାଟେରୀ ସେଭର୍ ବିଷୟରେ"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ଅନ୍ କରନ୍ତୁ"</string> - <string name="battery_saver_start_action" msgid="4553256017945469937">"ବ୍ୟାଟେରୀ ସେଭର୍ ଅନ୍ କରନ୍ତୁ"</string> - <string name="status_bar_settings_settings_button" msgid="534331565185171556">"ସେଟିଙ୍ଗ"</string> + <string name="battery_saver_start_action" msgid="4553256017945469937">"ବ୍ୟାଟେରୀ ସେଭର୍ ଚାଲୁ କରନ୍ତୁ"</string> + <string name="status_bar_settings_settings_button" msgid="534331565185171556">"ସେଟିଂସ୍"</string> <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"ୱାଇ-ଫାଇ"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ଅଟୋ-ରୋଟେଟ୍ ସ୍କ୍ରିନ୍"</string> <string name="status_bar_settings_mute_label" msgid="914392730086057522">"ମ୍ୟୁଟ୍"</string> @@ -91,7 +91,7 @@ <string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରିନ୍ ରେକର୍ଡ୍ ସେସନ୍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବେ?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"ରେକର୍ଡିଂ ସମୟରେ, Android ସିଷ୍ଟମ୍ ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ଚାଲୁଥିବା ଯେ କୌଣସି ସମ୍ବେଦନଶୀଳ ସୂଚନାକୁ କ୍ୟାପଚର୍ କରିପାରିବ। ଏହା ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ, ମେସେଜଗୁଡ଼ିକ ଏବଂ ଅଡିଓ ଅନ୍ତର୍ଭୁକ୍ତ କରେ।"</string> + <string name="screenrecord_description" msgid="1123231719680353736">"ରେକର୍ଡିଂ ସମୟରେ, Android ସିଷ୍ଟମ୍ ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ଚାଲୁଥିବା ଯେ କୌଣସି ସମ୍ବେଦନଶୀଳ ସୂଚନାକୁ କ୍ୟାପଚର୍ କରିପାରିବ। ଏଥିରେ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ, ମେସେଜ ଏବଂ ଅଡିଓ ଅନ୍ତର୍ଭୁକ୍ତ।"</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"ଅଡିଓ ରେକର୍ଡ କରନ୍ତୁ"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"ଡିଭାଇସ୍ ଅଡିଓ"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"ଆପଣଙ୍କ ଡିଭାଇସରୁ ସାଉଣ୍ଡ, ଯେପରିକି ସଙ୍ଗୀତ, କଲ୍ ଏବଂ ରିଂଟୋନଗୁଡ଼ିକ"</string> @@ -241,7 +241,7 @@ <string name="accessibility_battery_level" msgid="5143715405241138822">"ବ୍ୟାଟେରୀ <xliff:g id="NUMBER">%d</xliff:g> ଶତକଡ଼ା।"</string> <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ବ୍ୟାଟେରୀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ଶତକଡା, ଆପଣଙ୍କର ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string> <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ବ୍ୟାଟେରୀ ଚାର୍ଜ ହେଉଛି, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ଶତକଡ଼ା।"</string> - <string name="accessibility_settings_button" msgid="2197034218538913880">"ସିଷ୍ଟମ୍ ସେଟିଙ୍ଗ।"</string> + <string name="accessibility_settings_button" msgid="2197034218538913880">"ସିଷ୍ଟମ୍ ସେଟିଂସ୍।"</string> <string name="accessibility_notifications_button" msgid="3960913924189228831">"ବିଜ୍ଞପ୍ତି"</string> <string name="accessibility_overflow_action" msgid="8555835828182509104">"ସମସ୍ତ ବିଜ୍ଞପ୍ତି ଦେଖନ୍ତୁ"</string> <string name="accessibility_remove_notification" msgid="1641455251495815527">"ବିଜ୍ଞପ୍ତି ଖାଲି କରନ୍ତୁ।"</string> @@ -256,9 +256,9 @@ <skip /> <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା।"</string> <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ବିଜ୍ଞପ୍ତି ଶେଡ୍।"</string> - <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ଦ୍ରୁତ ସେଟିଙ୍ଗ।"</string> + <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ଦ୍ରୁତ ସେଟିଂସ୍।"</string> <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ଲକ୍ ସ୍କ୍ରୀନ୍।"</string> - <string name="accessibility_desc_settings" msgid="6728577365389151969">"ସେଟିଙ୍ଗ"</string> + <string name="accessibility_desc_settings" msgid="6728577365389151969">"ସେଟିଂସ୍"</string> <string name="accessibility_desc_recent_apps" msgid="1748675199348914194">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀ"</string> <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ୱର୍କ ଲକ୍ ସ୍କ୍ରୀନ୍"</string> <string name="accessibility_desc_close" msgid="8293708213442107755">"ବନ୍ଦ କରନ୍ତୁ"</string> @@ -328,8 +328,8 @@ <item quantity="one">ଭିତରେ ଆଉ <xliff:g id="NUMBER_0">%s</xliff:g>ଟି ଅଧିକ ବିଜ୍ଞପ୍ତି ରହିଛି।</item> </plurals> <string name="notification_summary_message_format" msgid="5158219088501909966">"<xliff:g id="CONTACT_NAME">%1$s</xliff:g>: <xliff:g id="MESSAGE_CONTENT">%2$s</xliff:g>"</string> - <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"ବିଜ୍ଞପ୍ତି ସେଟିଙ୍ଗ"</string> - <string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> ସେଟିଙ୍ଗ"</string> + <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"ବିଜ୍ଞପ୍ତି ସେଟିଂସ୍"</string> + <string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> ସେଟିଂସ୍"</string> <string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"ସ୍କ୍ରୀନ୍ ସ୍ୱଚାଳିତ ଭାବେ ବୁଲିବ।"</string> <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ଲ୍ୟାଣ୍ଡସ୍କେପ୍ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍କୁ ଲକ୍ କରାଯାଇଛି।"</string> <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ପୋର୍ଟ୍ରେଟ୍ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍କୁ ଲକ୍ କରାଯାଇଛି।"</string> @@ -355,7 +355,7 @@ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"ଶ୍ରବଣ ଯନ୍ତ୍ର"</string> <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ଅନ୍ ହେଉଛି…"</string> <string name="quick_settings_brightness_label" msgid="680259653088849563">"ଉଜ୍ଜ୍ୱଳତା"</string> - <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ସ୍ୱତଃ-ଘୂର୍ଣ୍ଣନ"</string> + <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ଅଟୋ-ରୋଟେଟ୍"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ଅଟୋ-ରୋଟେଟ୍ ସ୍କ୍ରିନ୍"</string> <string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> ମୋଡ୍"</string> <string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"ଘୂର୍ଣ୍ଣନ ଲକ୍ ହୋଇଛି"</string> @@ -367,11 +367,11 @@ <string name="quick_settings_media_device_label" msgid="8034019242363789941">"ମିଡିଆ ଡିଭାଇସ୍"</string> <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string> <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"କେବଳ ଜରୁରୀକାଳୀନ କଲ୍"</string> - <string name="quick_settings_settings_label" msgid="2214639529565474534">"ସେଟିଙ୍ଗ"</string> + <string name="quick_settings_settings_label" msgid="2214639529565474534">"ସେଟିଂସ୍"</string> <string name="quick_settings_time_label" msgid="3352680970557509303">"ସମୟ"</string> <string name="quick_settings_user_label" msgid="1253515509432672496">"ମୁଁ"</string> <string name="quick_settings_user_title" msgid="8673045967216204537">"ୟୁଜର୍"</string> - <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ନୂଆ ୟୁଜର୍"</string> + <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string> <string name="quick_settings_wifi_label" msgid="2879507532983487244">"ୱାଇ-ଫାଇ"</string> <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string> <string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"ନେଟ୍ୱର୍କ ନାହିଁ"</string> @@ -389,7 +389,7 @@ <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"ସ୍ୱଚାଳିତ"</string> <string name="quick_settings_inversion_label" msgid="5078769633069667698">"ରଙ୍ଗ ଇନଭାର୍ଟ୍ କରନ୍ତୁ"</string> <string name="quick_settings_color_space_label" msgid="537528291083575559">"ରଙ୍ଗ ସଂଶୋଧନ ମୋଡ୍"</string> - <string name="quick_settings_more_settings" msgid="2878235926753776694">"ଅଧିକ ସେଟିଙ୍ଗ"</string> + <string name="quick_settings_more_settings" msgid="2878235926753776694">"ଅଧିକ ସେଟିଂସ୍"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ହୋଇଗଲା"</string> <string name="quick_settings_connected" msgid="3873605509184830379">"ସଂଯୁକ୍ତ"</string> <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"କନେକ୍ଟ ରହିଛି, ବ୍ୟାଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> @@ -471,8 +471,8 @@ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"ୟୁଜର୍ ବଦଳାନ୍ତୁ, ବର୍ତ୍ତମାନର ୟୁଜର୍ ହେଉଛନ୍ତି <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string> <string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"ବର୍ତ୍ତମାନର ୟୁଜର୍ ହେଉଛନ୍ତି <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string> <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"ପ୍ରୋଫାଇଲ୍ ଦେଖାନ୍ତୁ"</string> - <string name="user_add_user" msgid="4336657383006913022">"ୟୁଜର୍ଙ୍କୁ ଯୋଡ଼ନ୍ତୁ"</string> - <string name="user_new_user_name" msgid="2019166282704195789">"ନୂତନ ୟୁଜର୍"</string> + <string name="user_add_user" msgid="4336657383006913022">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string> + <string name="user_new_user_name" msgid="2019166282704195789">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ଅବଧିର ସମସ୍ତ ଆପ୍ ଓ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</string> @@ -486,7 +486,7 @@ <string name="user_logout_notification_title" msgid="3644848998053832589">"ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍ କରନ୍ତୁ"</string> <string name="user_logout_notification_text" msgid="7441286737342997991">"ବର୍ତ୍ତମାନର ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍ କରନ୍ତୁ"</string> <string name="user_logout_notification_action" msgid="7974458760719361881">"ୟୁଜରଙ୍କୁ ଲଗଆଉଟ୍ କରନ୍ତୁ"</string> - <string name="user_add_user_title" msgid="4172327541504825032">"ନୂତନ ୟୁଜର୍ ଯୋଡ଼ିବେ?"</string> + <string name="user_add_user_title" msgid="4172327541504825032">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରିବେ?"</string> <string name="user_add_user_message_short" msgid="2599370307878014791">"ଜଣେ ନୂଆ ୟୁଜର୍ଙ୍କୁ ଯୋଡ଼ିବାବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ସ୍ଥାନ ସେଟ୍ କରିବାକୁ ପଡ଼ିବ। \n \n ଅନ୍ୟ ସମସ୍ତ ୟୁଜର୍ଙ୍କ ପାଇଁ ଯେକୌଣସି ୟୁଜର୍ ଆପ୍ଗୁଡ଼ିକୁ ଅପଡେଟ୍ କରିପାରିବେ।"</string> <string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string> <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398"> @@ -558,7 +558,7 @@ <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"ଅଧିକ ଜାଣନ୍ତୁ"</string> <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"ଆପଣ <xliff:g id="VPN_APP">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ ଅଛନ୍ତି, ଯାହା ଇମେଲ୍, ଆପ୍ ଓ ୱେବସାଇଟ୍ ସମେତ ଆପଣଙ୍କ ନେଟ୍ୱର୍କର ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରେ।"</string> <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> - <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ"</string> + <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ସେଟିଂସ୍ ଖୋଲନ୍ତୁ"</string> <string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string> <string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"ମୁକ୍ତ ବିଶ୍ୱସ୍ତ କ୍ରୀଡେନଶିଆଲ୍"</string> <string name="monitoring_description_network_logging" msgid="577305979174002252">"ଆପଣଙ୍କ ଆଡମିନ୍ ନେଟ୍ୱର୍କ ଲଗଇନ୍ କରିବା ଅନ୍ କରିଛନ୍ତି, ଯାହା ଆପଣଙ୍କ ଡିଭାଇସରେ ଟ୍ରାଫିକ୍ ନିରୀକ୍ଷଣ କରେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ନିଜ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string> @@ -579,7 +579,7 @@ <string name="hidden_notifications_setup" msgid="2064795578526982467">"ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string> <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> <string name="volume_zen_end_now" msgid="5901885672973736563">"ବର୍ତ୍ତମାନ ଅଫ୍ କରନ୍ତୁ"</string> - <string name="accessibility_volume_settings" msgid="1458961116951564784">"ସାଉଣ୍ଡ ସେଟିଙ୍ଗ"</string> + <string name="accessibility_volume_settings" msgid="1458961116951564784">"ସାଉଣ୍ଡ ସେଟିଂସ୍"</string> <string name="accessibility_volume_expand" msgid="7653070939304433603">"ବଢ଼ାନ୍ତୁ"</string> <string name="accessibility_volume_collapse" msgid="2746845391013829996">"ଛୋଟ କରନ୍ତୁ"</string> <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ସ୍ବଚାଳିତ କ୍ୟାପ୍ସନ୍ ମିଡିଆ"</string> @@ -610,7 +610,7 @@ <string name="stream_music" msgid="2188224742361847580">"ମିଡିଆ"</string> <string name="stream_alarm" msgid="16058075093011694">"ଆଲାର୍ମ"</string> <string name="stream_notification" msgid="7930294049046243939">"ବିଜ୍ଞପ୍ତି"</string> - <string name="stream_bluetooth_sco" msgid="6234562365528664331">"ବ୍ଲୁଟୂଥ୍"</string> + <string name="stream_bluetooth_sco" msgid="6234562365528664331">"ବ୍ଲୁଟୁଥ୍"</string> <string name="stream_dtmf" msgid="7322536356554673067">"ଡୁଆଲ୍ ମଲ୍ଟି ଟୋନ୍ ଫ୍ରିକ୍ୱେନ୍ସୀ"</string> <string name="stream_accessibility" msgid="3873610336741987152">"ଆକ୍ସେସିବିଲିଟୀ"</string> <string name="ring_toggle_title" msgid="5973120187287633224">"କଲ୍"</string> @@ -726,12 +726,12 @@ <string name="appops_camera_overlay" msgid="6466845606058816484">"ଏହି ଆପ୍, ଆପଣଙ୍କର ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍ ଉପରେ ପ୍ରଦର୍ଶିତ ହେଉଛି ଏବଂ କ୍ୟାମେରା ବ୍ୟବହାର କରୁଛି।"</string> <string name="appops_mic_overlay" msgid="4609326508944233061">"ଏହି ଆପ୍, ଆପଣଙ୍କର ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍ ଉପରେ ପ୍ରଦର୍ଶିତ ହେଉଛି ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ବ୍ୟବହାର କରୁଛି।"</string> <string name="appops_camera_mic_overlay" msgid="5584311236445644095">"ଏହି ଆପ୍, ଆପଣଙ୍କର ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍ ଉପରେ ପ୍ରଦର୍ଶିତ ହେଉଛି ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ଓ କ୍ୟାମେରା ବ୍ୟବହାର କରୁଛି।"</string> - <string name="notification_appops_settings" msgid="5208974858340445174">"ସେଟିଙ୍ଗ"</string> + <string name="notification_appops_settings" msgid="5208974858340445174">"ସେଟିଂସ୍"</string> <string name="notification_appops_ok" msgid="2177609375872784124">"ଠିକ୍ ଅଛି"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣ ଖୋଲା ଯାଇଛି"</string> <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣ ବନ୍ଦ ହୋଇଛି"</string> <string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"ଏହି ଚ୍ୟାନେଲରୁ ବିଜ୍ଞପ୍ତିକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string> - <string name="notification_more_settings" msgid="4936228656989201793">"ଅଧିକ ସେଟିଙ୍ଗ"</string> + <string name="notification_more_settings" msgid="4936228656989201793">"ଅଧିକ ସେଟିଂସ୍"</string> <string name="notification_app_settings" msgid="8963648463858039377">"କଷ୍ଟମାଇଜ୍ କରନ୍ତୁ"</string> <string name="notification_done" msgid="6215117625922713976">"ହୋଇଗଲା"</string> <string name="inline_undo" msgid="9026953267645116526">"ପୂର୍ବସ୍ଥାନକୁ ଫେରାଇଆଣନ୍ତୁ"</string> @@ -811,7 +811,7 @@ <string name="battery" msgid="769686279459897127">"ବ୍ୟାଟେରୀ"</string> <string name="clock" msgid="8978017607326790204">"ଘଣ୍ଟା"</string> <string name="headset" msgid="4485892374984466437">"ହେଡସେଟ୍"</string> - <string name="accessibility_long_click_tile" msgid="210472753156768705">"ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ"</string> + <string name="accessibility_long_click_tile" msgid="210472753156768705">"ସେଟିଂସ୍ ଖୋଲନ୍ତୁ"</string> <string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"ହେଡଫୋନ୍ ସଂଯୁକ୍ତ"</string> <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"ହେଡସେଟ୍ ସଂଯୁକ୍ତ"</string> <string name="data_saver" msgid="3484013368530820763">"ଡାଟା ସେଭର୍"</string> @@ -888,9 +888,9 @@ <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ଆପ୍ ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନକୁ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ କାମ ନକରିପାରେ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> - <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string> + <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ସେଟିଂସ୍ ଖୋଲନ୍ତୁ।"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string> - <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ବନ୍ଦ କରନ୍ତୁ।"</string> + <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ଦ୍ରୁତ ସେଟିଂସ୍ ବନ୍ଦ କରନ୍ତୁ।"</string> <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"ଆଲାର୍ମ ସେଟ୍।"</string> <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> ଭାବରେ ସାଇନ୍ ଇନ୍ କରିଛନ୍ତି"</string> <string name="data_connection_no_internet" msgid="691058178914184544">"କୌଣସି ଇଣ୍ଟରନେଟ୍ କନେକ୍ସନ୍ ନାହିଁ"</string> @@ -903,7 +903,7 @@ <string name="pip_phone_expand" msgid="1424988917240616212">"ବଢ଼ାନ୍ତୁ"</string> <string name="pip_phone_minimize" msgid="9057117033655996059">"ଛୋଟ କରନ୍ତୁ"</string> <string name="pip_phone_close" msgid="8801864042095341824">"ବନ୍ଦ କରନ୍ତୁ"</string> - <string name="pip_phone_settings" msgid="5687538631925004341">"ସେଟିଙ୍ଗ"</string> + <string name="pip_phone_settings" msgid="5687538631925004341">"ସେଟିଂସ୍"</string> <string name="pip_phone_dismiss_hint" msgid="5825740708095316710">"ଖାରଜ କରିବାକୁ ତଳକୁ ଟାଣନ୍ତୁ"</string> <string name="pip_menu_title" msgid="6365909306215631910">"ମେନୁ"</string> <string name="pip_notification_title" msgid="8661573026059630525">"<xliff:g id="NAME">%s</xliff:g> \"ଛବି-ଭିତରେ-ଛବି\"ରେ ଅଛି"</string> @@ -976,7 +976,7 @@ <string name="no_auto_saver_action" msgid="7467924389609773835">"ନାହିଁ, ଥାଉ"</string> <string name="auto_saver_enabled_title" msgid="4294726198280286333">"ଆଗରୁ ସେଟ୍ କରିଥିବା ସମୟ ଅନୁସାରେ ବ୍ୟାଟେରୀ ସେଭର୍ ଅନ୍ ହୋଇଛି"</string> <string name="auto_saver_enabled_text" msgid="7889491183116752719">"ଚାର୍ଜ <xliff:g id="PERCENTAGE">%d</xliff:g>%%ରୁ କମ୍ ହେଲେ ବ୍ୟାଟେରୀ ସେଭର୍ ଆପେ ଅନ୍ ହୋଇଯିବ।"</string> - <string name="open_saver_setting_action" msgid="2111461909782935190">"ସେଟିଙ୍ଗ"</string> + <string name="open_saver_setting_action" msgid="2111461909782935190">"ସେଟିଂସ୍"</string> <string name="auto_saver_okay_action" msgid="7815925750741935386">"ବୁଝିଗଲି"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ହିପ୍ ଡମ୍ପ୍ କରନ୍ତୁ"</string> <string name="sensor_privacy_mode" msgid="4462866919026513692">"ସେନ୍ସର୍ଗୁଡ଼ିକ ବନ୍ଦ ଅଛି"</string> @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ଯେ କୌଣସି ସମୟରେ ବବଲଗୁଡ଼ିକ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ଏହି ଆପର ବବଲଗୁଡ଼ିକ ବନ୍ଦ କରିବା ପାଇଁ \'ପରିଚାଳନା କରନ୍ତୁ\' ବଟନରେ ଟାପ୍ କରନ୍ତୁ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ବୁଝିଗଲି"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ସେଟିଂସ୍"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ବାର୍ତ୍ତାଳାପ ବିଭାଗର ଶୀର୍ଷରେ ଦେଖାନ୍ତୁ"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ଲକ୍ ସ୍କ୍ରିନରେ ପ୍ରୋଫାଇଲ୍ ଛବି ଦେଖାନ୍ତୁ"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ଆପଗୁଡ଼ିକ ଉପରେ ଫ୍ଲୋଟିଂ ବବଲ୍ ପରି ଦେଖାଯିବ"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\' ମୋଡରେ ବାଧା ଉପୁଯାଇପାରିବ"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ବୁଝିଗଲି"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ଓଭର୍ଲେ ୱିଣ୍ଡୋ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 4e6247acd3ab..88ae0360010d 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ਬਬਲ ਨੂੰ ਕਿਸੇ ਵੇਲੇ ਵੀ ਕੰਟਰੋਲ ਕਰੋ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ਇਸ ਐਪ \'ਤੇ ਬਬਲ ਬੰਦ ਕਰਨ ਲਈ \'ਪ੍ਰਬੰਧਨ ਕਰੋ\' \'ਤੇ ਟੈਪ ਕਰੋ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ਸਮਝ ਲਿਆ"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ਸੈਟਿੰਗਾਂ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਦੇ ਸਿਖਰ \'ਤੇ ਦਿਖਾਓ"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਦਿਖਾਓ"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ਐਪਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਫਲੋਟਿੰਗ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਵਿਘਨ ਪੈ ਸਕਦਾ ਹੈ"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ਸਮਝ ਲਿਆ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਓਵਰਲੇ Window"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window ਦੇ ਕੰਟਰੋਲ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index e577fd2cf5ac..4caf6ae5abb2 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -90,7 +90,7 @@ <string name="screenshot_preview_description" msgid="7606510140714080474">"Podgląd zrzutu ekranu"</string> <string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string> - <string name="screenrecord_start_label" msgid="1750350278888217473">"Rozpocząć rejestrowanie?"</string> + <string name="screenrecord_start_label" msgid="1750350278888217473">"Rozpocząć nagrywanie?"</string> <string name="screenrecord_description" msgid="1123231719680353736">"Podczas nagrywania system Android może rejestrować wszelkie informacji poufne wyświetlane na ekranie lub odtwarzane na urządzeniu. Dotyczy to m.in. haseł, szczegółów płatności, zdjęć, wiadomości i odtwarzanych dźwięków."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagraj dźwięk"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Dźwięki odtwarzane na urządzeniu"</string> @@ -108,7 +108,7 @@ <string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anuluj"</string> <string name="screenrecord_share_label" msgid="5025590804030086930">"Udostępnij"</string> <string name="screenrecord_delete_label" msgid="1376347010553987058">"Usuń"</string> - <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Anulowano rejestrowanie zawartości ekranu"</string> + <string name="screenrecord_cancel_success" msgid="1775448688137393901">"Anulowano nagrywanie zawartości ekranu"</string> <string name="screenrecord_save_message" msgid="490522052388998226">"Zapisano nagranie zawartości ekranu – kliknij, by je obejrzeć"</string> <string name="screenrecord_delete_description" msgid="1604522770162810570">"Usunięto nagranie zawartości ekranu"</string> <string name="screenrecord_delete_error" msgid="2870506119743013588">"Błąd podczas usuwania nagrania zawartości ekranu"</string> @@ -1009,8 +1009,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Zarządzaj dymkami w dowolnym momencie"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Kliknij Zarządzaj, aby wyłączyć dymki z tej aplikacji"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – ustawienia"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tryb gotowości"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 9a7f8174bc4b..db7dc624d842 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -101,7 +101,7 @@ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"A gravar o ecrã…"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"A gravar o ecrã e o áudio…"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques no ecrã"</string> - <string name="screenrecord_stop_text" msgid="6549288689506057686">"Tocar para parar"</string> + <string name="screenrecord_stop_text" msgid="6549288689506057686">"Toque para parar"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Parar"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"Colocar em pausa"</string> <string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões em qualquer altura"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em Gerir para desativar os balões desta app."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Definições de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Aceda às Definições para atualizar a navegação no sistema."</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index dc5c682a9985..37896aaa14a8 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -374,7 +374,7 @@ <string name="quick_settings_user_title" msgid="8673045967216204537">"Utilizator"</string> <string name="quick_settings_user_new_user" msgid="3347905871336069666">"Utilizator nou"</string> <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string> - <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Neconectat"</string> + <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"Neconectată"</string> <string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"Nicio rețea"</string> <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"Wi-Fi deconectat"</string> <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi activat"</string> @@ -1004,8 +1004,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlați oricând baloanele"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Atingeți Gestionați pentru a dezactiva baloanele din această aplicație"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Setări <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accesați Setările pentru a actualiza navigarea în sistem"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 1fde1e29a5e7..70083b037127 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ඕනෑම වේලාවක බුබුලු පාලනය කරන්න"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"මෙම යෙදුමෙන් බුබුලු ක්රියාවිරහිත කිරීමට කළමනාකරණය කරන්න තට්ටු කරන්න"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"තේරුණා"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> සැකසීම්"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"පොරොත්තු"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 7504f1510476..c71e4fa613e4 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -1009,8 +1009,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ovládajte bubliny kedykoľvek"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Klepnutím na Spravovať vypnite bubliny z tejto aplikácie"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Dobre"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavenia upozornenia <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostný režim"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index b4276015aa1f..d41b2a34727b 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -33,10 +33,10 @@ <string name="invalid_charger_title" msgid="938685362320735167">"Ni mogoče polniti prek USB-ja"</string> <string name="invalid_charger_text" msgid="2339310107232691577">"Uporabite polnilnik, ki je bil priložen napravi"</string> <string name="battery_low_why" msgid="2056750982959359863">"Nastavitve"</string> - <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Želite vklopiti varčevanje z energijo baterije?"</string> + <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Želite vklopiti varčevanje z baterijo?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"O varčevanju z energijo baterije"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Vklopi"</string> - <string name="battery_saver_start_action" msgid="4553256017945469937">"Vklop varčevanja z energijo baterije"</string> + <string name="battery_saver_start_action" msgid="4553256017945469937">"Vklop varčevanja z baterijo"</string> <string name="status_bar_settings_settings_button" msgid="534331565185171556">"Nastavitve"</string> <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Samodejno zasukaj zaslon"</string> @@ -1009,8 +1009,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačkov kadar koli"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dotaknite se »Upravljanje«, da izklopite oblačke iz te aplikacije"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumem"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavitve za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravljenosti"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index ae6089151c4b..bc07100c82c8 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -90,7 +90,7 @@ <string name="screenshot_preview_description" msgid="7606510140714080474">"Pamja paraprake e imazhit"</string> <string name="screenrecord_name" msgid="2596401223859996572">"Regjistruesi i ekranit"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string> - <string name="screenrecord_start_label" msgid="1750350278888217473">"Të niset regjistrimi?"</string> + <string name="screenrecord_start_label" msgid="1750350278888217473">"Të nis regjistrimi?"</string> <string name="screenrecord_description" msgid="1123231719680353736">"Gjatë regjistrimit, sistemi Android mund të regjistrojë çdo informacion delikat që është i dukshëm në ekranin tënd ose që luhet në pajisje. Kjo përfshin fjalëkalimet, informacionin e pagesave, fotografitë, mesazhet dhe audion."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Regjistro audio"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audioja e pajisjes"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollo flluskat në çdo moment"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trokit \"Menaxho\" për të çaktivizuar flluskat nga ky aplikacion"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"E kuptova"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Cilësimet e <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Në gatishmëri"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index c32626c917cb..b01dc4fd21bf 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -1004,8 +1004,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролишите облачиће у било ком тренутку"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Додирните Управљајте да бисте искључили облачиће из ове апликације"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Важи"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Подешавања за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 6ef1dfdc3e7d..c7943980b0e8 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -91,7 +91,7 @@ <string name="screenrecord_name" msgid="2596401223859996572">"Skärminspelare"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Vill du starta inspelningen?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"När du spelar kan Android-systemet registrera alla känsliga uppgifter som visas på skärmen eller spelas upp på enheten. Detta omfattar lösenord, betalningsuppgifter, foton, meddelanden och ljud."</string> + <string name="screenrecord_description" msgid="1123231719680353736">"När du spelar in kan Android-systemet registrera alla känsliga uppgifter som visas på skärmen eller spelas upp på enheten. Detta omfattar lösenord, betalningsuppgifter, foton, meddelanden och ljud."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Spela in ljud"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Ljud på enheten"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Ljud från enheten, till exempel musik, samtal och ringsignaler"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bubblor när som helst"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryck på Hantera för att stänga av bubblor från den här appen"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Inställningar för <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Öppna inställningarna och uppdatera systemnavigeringen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Viloläge"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index a0e31d2ceafb..6951872bde02 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -87,8 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"போதுமான சேமிப்பிடம் இல்லாததால் ஸ்கிரீன்ஷாட்டைச் சேமிக்க முடியவில்லை"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ஸ்கிரீன் ஷாட்டுகளை எடுப்பதை, ஆப்ஸ் அல்லது உங்கள் நிறுவனம் அனுமதிக்கவில்லை"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ஸ்கிரீன்ஷாட்டை நிராகரி"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"ஸ்கிரீன்ஷாட்டின் மாதிரிக்காட்சி"</string> <string name="screenrecord_name" msgid="2596401223859996572">"ஸ்கிரீன் ரெக்கார்டர்"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"ரெக்கார்டிங்கைத் தொடங்கவா?"</string> @@ -708,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"பபிள்"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"ஒலியோ அதிர்வோ இல்லாமல் முழு கவனம் செலுத்த உதவும்."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"ஒலியோ அதிர்வோ ஏற்படுத்தி உங்கள் கவனத்தை ஈர்க்கும்."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ஒலியோ அதிர்வோ ஏற்படுத்தி உங்கள் கவனத்தை ஈர்க்கும். <xliff:g id="APP_NAME">%1$s</xliff:g> இலிருந்து வரும் உரையாடல்கள் இயல்பாகவே குமிழ் வடிவில் தோன்றும்."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"இந்த உள்ளடக்கத்திற்கான மிதக்கும் ஷார்ட்கட் மூலம் உங்கள் கவனத்தைப் பெற்றிருக்கும்."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"உரையாடல் பிரிவின் மேற்பகுதியில் ஒரு குமிழாகக் காட்டப்படும்."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"அமைப்புகள்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index e74700923292..9a2b77fa388b 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"బబుల్స్ను ఎప్పుడైనా నియంత్రించండి"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ఈ యాప్ నుండి వచ్చే బబుల్స్ను ఆఫ్ చేయడానికి మేనేజ్ బటన్ను ట్యాప్ చేయండి"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"అర్థమైంది"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> సెట్టింగ్లు"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"సిస్టమ్ నావిగేషన్ అప్డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్లకు వెళ్లండి."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"సిస్టమ్ నావిగేషన్ను అప్డేట్ చేయడానికి సెట్టింగ్లకు వెళ్లండి"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"స్టాండ్బై"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"సంభాషణ విభాగంలో ఎగువున చూపబడుతుంది"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"లాక్ స్క్రీన్ మీద ప్రొఫైల్ ఫోటో చూపబడుతుంది"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"యాప్ల పైన తేలియాడే బబుల్లాగా కనిపిస్తాయి"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'అంతరాయం కలిగించవద్దు\' మోడ్కు అంతరాయం"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"అర్థమైంది"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"మాగ్నిఫికేషన్ ఓవర్లే విండో"</string> <string name="magnification_window_title" msgid="4863914360847258333">"మాగ్నిఫికేషన్ విండో"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"మాగ్నిఫికేషన్ నియంత్రణల విండో"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index bde22a53f15a..a51f62ee782a 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ควบคุมบับเบิลได้ทุกเมื่อ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"แตะ \"จัดการ\" เพื่อปิดบับเบิลจากแอปนี้"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"รับทราบ"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"การตั้งค่า <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"สแตนด์บาย"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index cafaaace6fdf..082b5c72ad0e 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolin ang mga bubble anumang oras"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"I-tap ang Pamahalaan para i-off ang mga bubble mula sa app na ito"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Mga setting ng <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Naka-standby"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index c9d53357caf6..d81066cb3c16 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Baloncukları istediğiniz zaman kontrol edin"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu uygulamanın baloncuklarını kapatmak için Yönet\'e dokunun"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Beklemeye alınıyor"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 00e9d58dd06f..a6da1b4b2a18 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -1009,8 +1009,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Налаштовуйте спливаючі чати будь-коли"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Натисніть \"Налаштувати\", щоб вимкнути спливаючі чати від цього додатка"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Зрозуміло"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Налаштування параметра \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим очікування"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 6cc8dd3f75c8..a993cb33c264 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -999,21 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کسی بھی وقت بلبلے کو کنٹرول کریں"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"اس ایپ سے بلبلوں کو آف کرنے کے لیے نظم کریں پر تھپتھپائیں"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"سمجھ آ گئی"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ترتیبات"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"گفتگو کے سیکشن میں سب سے اوپر دکھائیں"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"مقفل سکرین پر پروفائل کی تصویر دکھائیں"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ایپس کے سب سے اوپر فلوٹنگ بلبلہ کے طور پر ظاہر ہوں"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"مداخلت کریں ڈسٹرب نہ کریں"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"سمجھ آ گئی"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"میگنیفیکیشن اوورلے ونڈو"</string> <string name="magnification_window_title" msgid="4863914360847258333">"میگنیفکیشن ونڈو"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"میگنیفکیشن ونڈو کنٹرولز"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 43099f4f060d..b926d753b5db 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -508,7 +508,7 @@ <string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string> <string name="manage_notifications_history_text" msgid="57055985396576230">"Tarix"</string> <string name="notification_section_header_gentle" msgid="3044910806569985386">"Sokin bildirishnomalar"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"Bildirishnomalar bildirilishi"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"Bildirishnomalarning yuborilishi"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Barcha sokin bildirishnomalarni tozalash"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilingan"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index c0996af8051b..ed8b3a556998 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kiểm soát tùy chọn cài đặt bong bóng trò chuyện bất mọi lúc"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Nhấn vào nút Quản lý để tắt bong bóng trò chuyện từ ứng dụng này"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Cài đặt <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Chế độ chờ"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index fba35b2fe36e..6fe19c9efede 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"随时控制对话泡"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"点按“管理”按钮,可关闭来自此应用的对话泡"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>设置"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系统导航已更新。要进行更改,请转到“设置”。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"转到“设置”即可更新系统导航"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待机"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 3c0654292d94..9f4bf907ef98 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -97,7 +97,7 @@ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"裝置播放的音效,例如音樂、通話和鈴聲"</string> <string name="screenrecord_mic_label" msgid="2111264835791332350">"麥克風"</string> <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"裝置音訊和麥克風"</string> - <string name="screenrecord_start" msgid="330991441575775004">"開始錄影"</string> + <string name="screenrecord_start" msgid="330991441575775004">"開始"</string> <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"正在錄影螢幕畫面"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"錄影螢幕畫面和音訊"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"顯示輕觸螢幕的位置"</string> @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"隨時控制小視窗設定"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕按「管理」即可關閉此應用程式的小視窗"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統導覽已更新。如需變更,請前往「設定」。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"前往「設定」更新系統導覽"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index de15aff3adc0..94990c79b829 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"你隨時可以控管對話框的各項設定"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕觸 [管理] 即可關閉來自這個應用程式的對話框"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"我知道了"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"請前往「設定」更新系統操作機制"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index e9793422ebde..c9bef049e05e 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -999,8 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Lawula amabhamuza noma nini"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Thepha okuthi Phatha ukuvala amabhamuza kusuka kulolu hlelo lokusebenza"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ngiyezwa"</string> - <!-- no translation found for bubbles_app_settings (5779443644062348657) --> - <skip /> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> izilungiselelo"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ilindile"</string> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 2e217a5e83ea..82eda311da6a 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -246,10 +246,13 @@ <color name="control_list_popup_background">@*android:color/background_floating_material_dark</color> <color name="control_spinner_dropdown">@*android:color/foreground_material_dark</color> <color name="control_more_vert">@*android:color/foreground_material_dark</color> - <color name="control_enabled_light_background">@color/GM2_yellow_200</color> - <color name="control_enabled_thermo_heat_background">@color/GM2_red_200</color> - <color name="control_enabled_thermo_cool_background">@color/GM2_blue_200</color> - <color name="control_enabled_default_background">@color/GM2_blue_200</color> + <color name="control_enabled_light_background">#413C2D</color> + <color name="control_enabled_thermo_heat_background">#41312E</color> + <color name="control_enabled_thermo_cool_background">#303744</color> + <color name="control_enabled_default_background">#3C3D40</color> + <color name="control_enabled_heat_foreground">#FF8B66</color> + <color name="control_enabled_default_foreground">@color/GM2_blue_300</color> + <color name="control_enabled_cool_foreground">@color/GM2_blue_300</color> <!-- Docked misalignment message --> <color name="misalignment_text_color">#F28B82</color> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index bad18cf67d98..48648e547a84 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -326,6 +326,7 @@ <dimen name="screenshot_action_chip_padding_middle">8dp</dimen> <dimen name="screenshot_action_chip_padding_end">16dp</dimen> <dimen name="screenshot_action_chip_text_size">14sp</dimen> + <dimen name="screenshot_dismissal_height_delta">80dp</dimen> <!-- The width of the view containing navigation buttons --> @@ -625,6 +626,15 @@ <!-- The height of the gap between adjacent notification sections. --> <dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen> + <!-- Size of the face pile shown on one-line (children of a group) conversation notifications --> + <dimen name="conversation_single_line_face_pile_size">36dp</dimen> + + <!-- Size of an avatar shown on one-line (children of a group) conversation notifications --> + <dimen name="conversation_single_line_avatar_size">24dp</dimen> + + <!-- Border width for avatars in the face pile shown on one-line (children of a group) conversation notifications --> + <dimen name="conversation_single_line_face_pile_protection_width">1dp</dimen> + <!-- The minimum amount of top overscroll to go to the quick settings. --> <dimen name="min_top_overscroll_to_qs">36dp</dimen> @@ -748,7 +758,7 @@ <!-- The top padding of the clear all button --> <dimen name="clear_all_padding_top">12dp</dimen> - <dimen name="notification_section_header_height">56dp</dimen> + <dimen name="notification_section_header_height">48dp</dimen> <dimen name="notification_section_header_padding_left">16dp</dimen> <!-- Largest size an avatar might need to be drawn in the user picker, status bar, or @@ -1295,4 +1305,9 @@ <!-- Opacity at which the background for the shutdown UI will be drawn. --> <item name="shutdown_scrim_behind_alpha" format="float" type="dimen">0.95</item> + + <!-- Allow CornerHandleView and PathSpecCornerPathRenderer to decouple from corner-radius --> + <dimen name="config_rounded_mask_size">@*android:dimen/rounded_corner_radius</dimen> + <dimen name="config_rounded_mask_size_top">@*android:dimen/rounded_corner_radius_top</dimen> + <dimen name="config_rounded_mask_size_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index d639ed074240..fd9a8d1dca7e 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -644,6 +644,9 @@ <!-- Content description to tell the user a notification has been removed from the notification shade --> <string name="accessibility_notification_dismissed">Notification dismissed.</string> + <!-- Content description to tell the user a bubble has been dismissed. --> + <string name="accessibility_bubble_dismissed">Bubble dismissed.</string> + <!-- Content description for the notification shade panel (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_desc_notification_shade">Notification shade.</string> <!-- Content description for the quick settings panel (not shown on the screen). [CHAR LIMIT=NONE] --> @@ -1021,6 +1024,9 @@ <!-- QuickSettings: Text to prompt the user to stop an ongoing recording [CHAR LIMIT=20] --> <string name="quick_settings_screen_record_stop">Stop</string> + <!-- Default name for the media device shown in the output switcher when the name is not available [CHAR LIMIT=30] --> + <string name="media_seamless_remote_device">Device</string> + <!-- Recents: Text that shows above the navigation bar after launching a few apps. [CHAR LIMIT=NONE] --> <string name="recents_swipe_up_onboarding">Swipe up to switch apps</string> <!-- Recents: Text that shows above the navigation bar after launching several apps. [CHAR LIMIT=NONE] --> @@ -1844,6 +1850,9 @@ <!-- [CHAR LIMIT=150] Notification Importance title: important conversation level --> <string name="notification_priority_title">Priority</string> + <!-- Text shown in notification guts for conversation notifications that don't implement the full feature --> + <string name="no_shortcut"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> does not support conversation specific settings</string> + <!-- [CHAR LIMIT=NONE] Empty overflow title --> <string name="bubble_overflow_empty_title">No recent bubbles</string> @@ -2690,6 +2699,9 @@ <!-- Controls management editing screen, text to indicate that all the favorites have been removed [CHAR LIMIT=NONE] --> <string name="controls_favorite_removed">All controls removed</string> + <!-- Controls management favorites screen, See other apps with changes made [CHAR LIMIT=NONE] --> + <string name="controls_favorite_toast_no_changes">Changes not saved</string> + <!-- Controls management controls screen error on load message [CHAR LIMIT=60] --> <string name="controls_favorite_load_error">The list of all controls could not be loaded.</string> <!-- Controls management controls screen header for Other zone [CHAR LIMIT=60] --> @@ -2708,6 +2720,8 @@ <string name="controls_pin_use_alphanumeric">PIN contains letters or symbols</string> <!-- Controls PIN entry dialog, title [CHAR LIMIT=30] --> <string name="controls_pin_verify">Verify <xliff:g id="device" example="Backdoor lock">%s</xliff:g></string> + <!-- Controls PIN entry dialog, title when 1st attempt failed [CHAR LIMIT=30] --> + <string name="controls_pin_wrong">Wrong PIN</string> <!-- Controls PIN entry dialog, waiting to verify [CHAR LIMIT=30] --> <string name="controls_pin_verifying">Verifying\u2026</string> <!-- Controls PIN entry dialog, text hint [CHAR LIMIT=30] --> @@ -2731,6 +2745,13 @@ <!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] --> <string name="controls_error_timeout">Inactive, check app</string> + <!-- Error message indicating that an unspecified error occurred while getting the status, and + a retry will be attempted [CHAR LIMIT=30] --> + <string name="controls_error_retryable">Error, retrying\u2026</string> + <!-- Error message indicating that the control is no longer available in the application [CHAR LIMIT=30] --> + <string name="controls_error_removed">Device removed</string> + <!-- Error message indicating that an unspecified error occurred while getting the status [CHAR LIMIT=30] --> + <string name="controls_error_generic">Can\u2019t load status</string> <!-- Error message indicating that a control action failed [CHAR_LIMIT=30] --> <string name="controls_error_failed">Error, try again</string> <!-- Stateless control message informing the user that a routine has started [CHAR_LIMIT=30] --> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 26ae79081491..57d2040bed57 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -258,7 +258,7 @@ <style name="TextAppearance.AuthCredential.Title"> <item name="android:fontFamily">google-sans</item> - <item name="android:paddingTop">16dp</item> + <item name="android:paddingTop">12dp</item> <item name="android:paddingHorizontal">24dp</item> <item name="android:textSize">24sp</item> </style> @@ -278,7 +278,7 @@ </style> <style name="TextAppearance.AuthCredential.Error"> - <item name="android:paddingTop">12dp</item> + <item name="android:paddingTop">6dp</item> <item name="android:paddingHorizontal">24dp</item> <item name="android:textSize">14sp</item> <item name="android:textColor">?android:attr/colorError</item> @@ -475,7 +475,6 @@ <item name="android:textColor">?android:attr/textColorTertiary</item> </style> - <style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless"> <item name="android:background">@drawable/btn_borderless_rect</item> </style> @@ -573,7 +572,7 @@ parent="@android:style/Widget.Material.Button.Borderless"> <item name="android:textColor">?attr/wallpaperTextColor</item> <item name="android:textAllCaps">false</item> - <item name="android:textSize">16sp</item> + <item name="android:textSize">14sp</item> </style> <style name="TextAppearance.HeadsUpStatusBarText" @@ -670,6 +669,7 @@ <item name="android:colorBackground">@android:color/black</item> <item name="android:windowAnimationStyle">@null</item> <item name="android:statusBarColor">@*android:color/transparent</item> + <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item> </style> <style name="TextAppearance.Control"> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java index b8997c29dd52..c8607df8fe0b 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java @@ -256,13 +256,9 @@ public class PluginInstanceManager<T extends Plugin> { case QUERY_ALL: if (DEBUG) Log.d(TAG, "queryAll " + mAction); for (int i = mPlugins.size() - 1; i >= 0; i--) { - PluginInfo<T> plugin = mPlugins.get(i); - mListener.onPluginDisconnected(plugin.mPlugin); - if (!(plugin.mPlugin instanceof PluginFragment)) { - // Only call onDestroy for plugins that aren't fragments, as fragments - // will get the onDestroy as part of the fragment lifecycle. - plugin.mPlugin.onDestroy(); - } + PluginInfo<T> pluginInfo = mPlugins.get(i); + mMainHandler.obtainMessage( + MainHandler.PLUGIN_DISCONNECTED, pluginInfo.mPlugin).sendToTarget(); } mPlugins.clear(); handleQueryPlugins(null); diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java index 9e9b9dc4f3b0..dd5cc7c9bbd4 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java @@ -38,7 +38,7 @@ public abstract class TaskStackChangeListener { public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { } public void onActivityUnpinned() { } public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask) { } + boolean clearedTask, boolean wasVisible) { } public void onActivityForcedResizable(String packageName, int taskId, int reason) { } public void onActivityDismissingDockedStack() { } public void onActivityLaunchOnSecondaryDisplayFailed() { } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java index ce9cbabaa5e9..a76a901c5c81 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java @@ -122,11 +122,12 @@ public class TaskStackChangeListeners extends TaskStackListener { @Override public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask) throws RemoteException { + boolean clearedTask, boolean wasVisible) throws RemoteException { final SomeArgs args = SomeArgs.obtain(); args.arg1 = task; args.argi1 = homeTaskVisible ? 1 : 0; args.argi2 = clearedTask ? 1 : 0; + args.argi3 = wasVisible ? 1 : 0; mHandler.removeMessages(H.ON_ACTIVITY_RESTART_ATTEMPT); mHandler.obtainMessage(H.ON_ACTIVITY_RESTART_ATTEMPT, args).sendToTarget(); } @@ -305,9 +306,10 @@ public class TaskStackChangeListeners extends TaskStackListener { final RunningTaskInfo task = (RunningTaskInfo) args.arg1; final boolean homeTaskVisible = args.argi1 != 0; final boolean clearedTask = args.argi2 != 0; + final boolean wasVisible = args.argi3 != 0; for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { mTaskStackListeners.get(i).onActivityRestartAttempt(task, - homeTaskVisible, clearedTask); + homeTaskVisible, clearedTask, wasVisible); } break; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 9cfcc52134ce..b99fb057ee65 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -56,6 +56,9 @@ import androidx.dynamicanimation.animation.DynamicAnimation; import androidx.dynamicanimation.animation.SpringAnimation; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; +import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; @@ -95,6 +98,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe // How much to scale the default slop by, to avoid accidental drags. private static final float SLOP_SCALE = 4f; + private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl(); + private KeyguardSecurityModel mSecurityModel; private LockPatternUtils mLockPatternUtils; @@ -178,6 +183,44 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe public void onCancelClicked(); } + @VisibleForTesting + public enum BouncerUiEvent implements UiEventLogger.UiEventEnum { + @UiEvent(doc = "Default UiEvent used for variable initialization.") + UNKNOWN(0), + + @UiEvent(doc = "Bouncer is dismissed using extended security access.") + BOUNCER_DISMISS_EXTENDED_ACCESS(413), + + @UiEvent(doc = "Bouncer is dismissed using biometric.") + BOUNCER_DISMISS_BIOMETRIC(414), + + @UiEvent(doc = "Bouncer is dismissed without security access.") + BOUNCER_DISMISS_NONE_SECURITY(415), + + @UiEvent(doc = "Bouncer is dismissed using password security.") + BOUNCER_DISMISS_PASSWORD(416), + + @UiEvent(doc = "Bouncer is dismissed using sim security access.") + BOUNCER_DISMISS_SIM(417), + + @UiEvent(doc = "Bouncer is successfully unlocked using password.") + BOUNCER_PASSWORD_SUCCESS(418), + + @UiEvent(doc = "An attempt to unlock bouncer using password has failed.") + BOUNCER_PASSWORD_FAILURE(419); + + private final int mId; + + BouncerUiEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } + } + public KeyguardSecurityContainer(Context context, AttributeSet attrs) { this(context, attrs, 0); } @@ -574,17 +617,21 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe boolean finish = false; boolean strongAuth = false; int eventSubtype = -1; + BouncerUiEvent uiEvent = BouncerUiEvent.UNKNOWN; if (mUpdateMonitor.getUserHasTrust(targetUserId)) { finish = true; eventSubtype = BOUNCER_DISMISS_EXTENDED_ACCESS; + uiEvent = BouncerUiEvent.BOUNCER_DISMISS_EXTENDED_ACCESS; } else if (mUpdateMonitor.getUserUnlockedWithBiometric(targetUserId)) { finish = true; eventSubtype = BOUNCER_DISMISS_BIOMETRIC; + uiEvent = BouncerUiEvent.BOUNCER_DISMISS_BIOMETRIC; } else if (SecurityMode.None == mCurrentSecuritySelection) { SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); if (SecurityMode.None == securityMode) { finish = true; // no security required eventSubtype = BOUNCER_DISMISS_NONE_SECURITY; + uiEvent = BouncerUiEvent.BOUNCER_DISMISS_NONE_SECURITY; } else { showSecurityScreen(securityMode); // switch to the alternate security view } @@ -596,6 +643,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe strongAuth = true; finish = true; eventSubtype = BOUNCER_DISMISS_PASSWORD; + uiEvent = BouncerUiEvent.BOUNCER_DISMISS_PASSWORD; break; case SimPin: @@ -606,6 +654,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe KeyguardUpdateMonitor.getCurrentUser())) { finish = true; eventSubtype = BOUNCER_DISMISS_SIM; + uiEvent = BouncerUiEvent.BOUNCER_DISMISS_SIM; } else { showSecurityScreen(securityMode); } @@ -630,6 +679,9 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe mMetricsLogger.write(new LogMaker(MetricsEvent.BOUNCER) .setType(MetricsEvent.TYPE_DISMISS).setSubtype(eventSubtype)); } + if (uiEvent != BouncerUiEvent.UNKNOWN) { + sUiEventLogger.log(uiEvent); + } if (finish) { mSecurityCallback.finish(strongAuth, targetUserId); } @@ -735,6 +787,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe } mMetricsLogger.write(new LogMaker(MetricsEvent.BOUNCER) .setType(success ? MetricsEvent.TYPE_SUCCESS : MetricsEvent.TYPE_FAILURE)); + sUiEventLogger.log(success ? BouncerUiEvent.BOUNCER_PASSWORD_SUCCESS + : BouncerUiEvent.BOUNCER_PASSWORD_FAILURE); } public void reset() { diff --git a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java index 85ce313670e3..cf7ee3a5753f 100644 --- a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java +++ b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java @@ -168,14 +168,14 @@ public class CornerHandleView extends View { // Attempt to get the bottom corner radius, otherwise fall back on the generic or top // values. If none are available, use the FALLBACK_RADIUS_DP. int radius = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.rounded_corner_radius_bottom); + com.android.systemui.R.dimen.config_rounded_mask_size_bottom); if (radius == 0) { radius = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.rounded_corner_radius); + com.android.systemui.R.dimen.config_rounded_mask_size); } if (radius == 0) { radius = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.rounded_corner_radius_top); + com.android.systemui.R.dimen.config_rounded_mask_size_top); } if (radius == 0) { radius = (int) convertDpToPixel(FALLBACK_RADIUS_DP, mContext); diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index cbdae4e6fe63..c84701c9512e 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -139,7 +139,7 @@ public class SystemUIApplication extends Application implements */ public void startServicesIfNeeded() { - String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents); + String[] names = SystemUIFactory.getInstance().getSystemUIServiceComponents(getResources()); startServicesIfNeeded(/* metricsPrefix= */ "StartServices", names); } @@ -150,8 +150,8 @@ public class SystemUIApplication extends Application implements * <p>This method must only be called from the main thread.</p> */ void startSecondaryUserServicesIfNeeded() { - String[] names = - getResources().getStringArray(R.array.config_systemUIServiceComponentsPerUser); + String[] names = SystemUIFactory.getInstance().getSystemUIServiceComponentsPerUser( + getResources()); startServicesIfNeeded(/* metricsPrefix= */ "StartSecondaryServices", names); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index fb40774a1f5c..be82a2d5325b 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -18,6 +18,7 @@ package com.android.systemui; import android.annotation.NonNull; import android.content.Context; +import android.content.res.Resources; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -120,6 +121,16 @@ public class SystemUIFactory { return mRootComponent; } + /** Returns the list of system UI components that should be started. */ + public String[] getSystemUIServiceComponents(Resources resources) { + return resources.getStringArray(R.array.config_systemUIServiceComponents); + } + + /** Returns the list of system UI components that should be started per user. */ + public String[] getSystemUIServiceComponentsPerUser(Resources resources) { + return resources.getStringArray(R.array.config_systemUIServiceComponentsPerUser); + } + /** * Creates an instance of ScreenshotNotificationSmartActionsProvider. * This method is overridden in vendor specific implementation of Sys UI. diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java index 1f27ae238533..73dfd32d03a2 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java @@ -18,6 +18,8 @@ package com.android.systemui.accessibility; import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS; +import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME; + import android.accessibilityservice.AccessibilityService; import android.app.PendingIntent; import android.app.RemoteAction; @@ -25,6 +27,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.Configuration; import android.graphics.drawable.Icon; import android.hardware.input.InputManager; import android.os.Handler; @@ -32,6 +35,7 @@ import android.os.Looper; import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemClock; +import android.os.UserHandle; import android.util.Log; import android.view.Display; import android.view.IWindowManager; @@ -43,12 +47,15 @@ import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; import com.android.internal.R; +import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity; import com.android.internal.util.ScreenshotHelper; import com.android.systemui.Dependency; import com.android.systemui.SystemUI; import com.android.systemui.recents.Recents; import com.android.systemui.statusbar.phone.StatusBar; +import java.util.Locale; + import javax.inject.Inject; import javax.inject.Singleton; @@ -58,7 +65,6 @@ import javax.inject.Singleton; @Singleton public class SystemActions extends SystemUI { private static final String TAG = "SystemActions"; - // TODO(b/147916452): add implementation on launcher side to register this action. /** * Action ID to go back. @@ -96,12 +102,6 @@ public class SystemActions extends SystemUI { AccessibilityService.GLOBAL_ACTION_POWER_DIALOG; // = 6 /** - * Action ID to toggle docking the current app's window - */ - private static final int SYSTEM_ACTION_ID_TOGGLE_SPLIT_SCREEN = - AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN; // = 7 - - /** * Action ID to lock the screen */ private static final int SYSTEM_ACTION_ID_LOCK_SCREEN = @@ -114,13 +114,22 @@ public class SystemActions extends SystemUI { AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT; // = 9 /** - * Action ID to show accessibility menu + * Action ID to trigger the accessibility button + */ + public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON = + AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_BUTTON; // 11 + + /** + * Action ID to show accessibility button's menu of services */ - private static final int SYSTEM_ACTION_ID_ACCESSIBILITY_MENU = 10; + public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER = + AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER; // 12 private Recents mRecents; private StatusBar mStatusBar; private SystemActionsBroadcastReceiver mReceiver; + private Locale mLocale; + private AccessibilityManager mA11yManager; @Inject public SystemActions(Context context) { @@ -128,96 +137,139 @@ public class SystemActions extends SystemUI { mRecents = Dependency.get(Recents.class); mStatusBar = Dependency.get(StatusBar.class); mReceiver = new SystemActionsBroadcastReceiver(); + mLocale = mContext.getResources().getConfiguration().getLocales().get(0); + mA11yManager = (AccessibilityManager) mContext.getSystemService( + Context.ACCESSIBILITY_SERVICE); } @Override public void start() { mContext.registerReceiverForAllUsers(mReceiver, mReceiver.createIntentFilter(), null, null); + registerActions(); + } - // TODO(b/148087487): update the icon used below to a valid one - RemoteAction actionBack = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_back_label), - mContext.getString(R.string.accessibility_system_action_back_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_BACK)); - RemoteAction actionHome = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_home_label), - mContext.getString(R.string.accessibility_system_action_home_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_HOME)); - - RemoteAction actionRecents = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_recents_label), - mContext.getString(R.string.accessibility_system_action_recents_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS)); - - RemoteAction actionNotifications = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_notifications_label), - mContext.getString(R.string.accessibility_system_action_notifications_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS)); - - RemoteAction actionQuickSettings = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_quick_settings_label), - mContext.getString(R.string.accessibility_system_action_quick_settings_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS)); - - RemoteAction actionPowerDialog = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_power_dialog_label), - mContext.getString(R.string.accessibility_system_action_power_dialog_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG)); - - RemoteAction actionToggleSplitScreen = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_toggle_split_screen_label), - mContext.getString(R.string.accessibility_system_action_toggle_split_screen_label), - mReceiver.createPendingIntent( - mContext, - SystemActionsBroadcastReceiver.INTENT_ACTION_TOGGLE_SPLIT_SCREEN)); + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + final Locale locale = mContext.getResources().getConfiguration().getLocales().get(0); + if (!locale.equals(mLocale)) { + mLocale = locale; + registerActions(); + } + } - RemoteAction actionLockScreen = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_lock_screen_label), - mContext.getString(R.string.accessibility_system_action_lock_screen_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN)); + private void registerActions() { + RemoteAction actionBack = createRemoteAction( + R.string.accessibility_system_action_back_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_BACK); + + RemoteAction actionHome = createRemoteAction( + R.string.accessibility_system_action_home_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_HOME); + + RemoteAction actionRecents = createRemoteAction( + R.string.accessibility_system_action_recents_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS); + + RemoteAction actionNotifications = createRemoteAction( + R.string.accessibility_system_action_notifications_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS); + + RemoteAction actionQuickSettings = createRemoteAction( + R.string.accessibility_system_action_quick_settings_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS); + + RemoteAction actionPowerDialog = createRemoteAction( + R.string.accessibility_system_action_power_dialog_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG); + + RemoteAction actionLockScreen = createRemoteAction( + R.string.accessibility_system_action_lock_screen_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN); + + RemoteAction actionTakeScreenshot = createRemoteAction( + R.string.accessibility_system_action_screenshot_label, + SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT); + + mA11yManager.registerSystemAction(actionBack, SYSTEM_ACTION_ID_BACK); + mA11yManager.registerSystemAction(actionHome, SYSTEM_ACTION_ID_HOME); + mA11yManager.registerSystemAction(actionRecents, SYSTEM_ACTION_ID_RECENTS); + mA11yManager.registerSystemAction(actionNotifications, SYSTEM_ACTION_ID_NOTIFICATIONS); + mA11yManager.registerSystemAction(actionQuickSettings, SYSTEM_ACTION_ID_QUICK_SETTINGS); + mA11yManager.registerSystemAction(actionPowerDialog, SYSTEM_ACTION_ID_POWER_DIALOG); + mA11yManager.registerSystemAction(actionLockScreen, SYSTEM_ACTION_ID_LOCK_SCREEN); + mA11yManager.registerSystemAction(actionTakeScreenshot, SYSTEM_ACTION_ID_TAKE_SCREENSHOT); + } - RemoteAction actionTakeScreenshot = new RemoteAction( - Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_screenshot_label), - mContext.getString(R.string.accessibility_system_action_screenshot_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT)); + /** + * Register a system action. + * @param actionId the action ID to register. + */ + public void register(int actionId) { + int labelId; + String intent; + switch (actionId) { + case SYSTEM_ACTION_ID_BACK: + labelId = R.string.accessibility_system_action_back_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_BACK; + break; + case SYSTEM_ACTION_ID_HOME: + labelId = R.string.accessibility_system_action_home_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_HOME; + break; + case SYSTEM_ACTION_ID_RECENTS: + labelId = R.string.accessibility_system_action_recents_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS; + break; + case SYSTEM_ACTION_ID_NOTIFICATIONS: + labelId = R.string.accessibility_system_action_notifications_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS; + break; + case SYSTEM_ACTION_ID_QUICK_SETTINGS: + labelId = R.string.accessibility_system_action_quick_settings_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS; + break; + case SYSTEM_ACTION_ID_POWER_DIALOG: + labelId = R.string.accessibility_system_action_power_dialog_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG; + break; + case SYSTEM_ACTION_ID_LOCK_SCREEN: + labelId = R.string.accessibility_system_action_lock_screen_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN; + break; + case SYSTEM_ACTION_ID_TAKE_SCREENSHOT: + labelId = R.string.accessibility_system_action_screenshot_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT; + break; + case SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON: + labelId = R.string.accessibility_system_action_accessibility_button_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON; + break; + case SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER: + labelId = R.string.accessibility_system_action_accessibility_button_chooser_label; + intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER; + break; + default: + return; + } + mA11yManager.registerSystemAction(createRemoteAction(labelId, intent), actionId); + } - RemoteAction actionAccessibilityMenu = new RemoteAction( + private RemoteAction createRemoteAction(int labelId, String intent) { + // TODO(b/148087487): update the icon used below to a valid one + return new RemoteAction( Icon.createWithResource(mContext, R.drawable.ic_info), - mContext.getString(R.string.accessibility_system_action_accessibility_menu_label), - mContext.getString(R.string.accessibility_system_action_accessibility_menu_label), - mReceiver.createPendingIntent( - mContext, SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_MENU)); - - AccessibilityManager am = (AccessibilityManager) mContext.getSystemService( - Context.ACCESSIBILITY_SERVICE); + mContext.getString(labelId), + mContext.getString(labelId), + mReceiver.createPendingIntent(mContext, intent)); + } - am.registerSystemAction(actionBack, SYSTEM_ACTION_ID_BACK); - am.registerSystemAction(actionHome, SYSTEM_ACTION_ID_HOME); - am.registerSystemAction(actionRecents, SYSTEM_ACTION_ID_RECENTS); - am.registerSystemAction(actionNotifications, SYSTEM_ACTION_ID_NOTIFICATIONS); - am.registerSystemAction(actionQuickSettings, SYSTEM_ACTION_ID_QUICK_SETTINGS); - am.registerSystemAction(actionPowerDialog, SYSTEM_ACTION_ID_POWER_DIALOG); - am.registerSystemAction(actionToggleSplitScreen, SYSTEM_ACTION_ID_TOGGLE_SPLIT_SCREEN); - am.registerSystemAction(actionLockScreen, SYSTEM_ACTION_ID_LOCK_SCREEN); - am.registerSystemAction(actionTakeScreenshot, SYSTEM_ACTION_ID_TAKE_SCREENSHOT); - am.registerSystemAction(actionAccessibilityMenu, SYSTEM_ACTION_ID_ACCESSIBILITY_MENU); + /** + * Unregister a system action. + * @param actionId the action ID to unregister. + */ + public void unregister(int actionId) { + mA11yManager.unregisterSystemAction(actionId); } private void handleBack() { @@ -266,10 +318,6 @@ public class SystemActions extends SystemUI { } } - private void handleToggleSplitScreen() { - mStatusBar.toggleSplitScreen(); - } - private void handleLockScreen() { IWindowManager windowManager = WindowManagerGlobal.getWindowManagerService(); @@ -288,11 +336,19 @@ public class SystemActions extends SystemUI { SCREENSHOT_GLOBAL_ACTIONS, new Handler(Looper.getMainLooper()), null); } - private void handleAccessibilityMenu() { + private void handleAccessibilityButton() { AccessibilityManager.getInstance(mContext).notifyAccessibilityButtonClicked( Display.DEFAULT_DISPLAY); } + private void handleAccessibilityButtonChooser() { + final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + final String chooserClassName = AccessibilityButtonChooserActivity.class.getName(); + intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName); + mContext.startActivityAsUser(intent, UserHandle.CURRENT); + } + private class SystemActionsBroadcastReceiver extends BroadcastReceiver { private static final String INTENT_ACTION_BACK = "SYSTEM_ACTION_BACK"; private static final String INTENT_ACTION_HOME = "SYSTEM_ACTION_HOME"; @@ -300,12 +356,12 @@ public class SystemActions extends SystemUI { private static final String INTENT_ACTION_NOTIFICATIONS = "SYSTEM_ACTION_NOTIFICATIONS"; private static final String INTENT_ACTION_QUICK_SETTINGS = "SYSTEM_ACTION_QUICK_SETTINGS"; private static final String INTENT_ACTION_POWER_DIALOG = "SYSTEM_ACTION_POWER_DIALOG"; - private static final String INTENT_ACTION_TOGGLE_SPLIT_SCREEN = - "SYSTEM_ACTION_TOGGLE_SPLIT_SCREEN"; private static final String INTENT_ACTION_LOCK_SCREEN = "SYSTEM_ACTION_LOCK_SCREEN"; private static final String INTENT_ACTION_TAKE_SCREENSHOT = "SYSTEM_ACTION_TAKE_SCREENSHOT"; - private static final String INTENT_ACTION_ACCESSIBILITY_MENU = - "SYSTEM_ACTION_ACCESSIBILITY_MENU"; + private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON = + "SYSTEM_ACTION_ACCESSIBILITY_BUTTON"; + private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER = + "SYSTEM_ACTION_ACCESSIBILITY_BUTTON_MENU"; private PendingIntent createPendingIntent(Context context, String intentAction) { switch (intentAction) { @@ -315,10 +371,10 @@ public class SystemActions extends SystemUI { case INTENT_ACTION_NOTIFICATIONS: case INTENT_ACTION_QUICK_SETTINGS: case INTENT_ACTION_POWER_DIALOG: - case INTENT_ACTION_TOGGLE_SPLIT_SCREEN: case INTENT_ACTION_LOCK_SCREEN: case INTENT_ACTION_TAKE_SCREENSHOT: - case INTENT_ACTION_ACCESSIBILITY_MENU: { + case INTENT_ACTION_ACCESSIBILITY_BUTTON: + case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER: { Intent intent = new Intent(intentAction); return PendingIntent.getBroadcast(context, 0, intent, 0); } @@ -336,10 +392,10 @@ public class SystemActions extends SystemUI { intentFilter.addAction(INTENT_ACTION_NOTIFICATIONS); intentFilter.addAction(INTENT_ACTION_QUICK_SETTINGS); intentFilter.addAction(INTENT_ACTION_POWER_DIALOG); - intentFilter.addAction(INTENT_ACTION_TOGGLE_SPLIT_SCREEN); intentFilter.addAction(INTENT_ACTION_LOCK_SCREEN); intentFilter.addAction(INTENT_ACTION_TAKE_SCREENSHOT); - intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_MENU); + intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON); + intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER); return intentFilter; } @@ -371,10 +427,6 @@ public class SystemActions extends SystemUI { handlePowerDialog(); break; } - case INTENT_ACTION_TOGGLE_SPLIT_SCREEN: { - handleToggleSplitScreen(); - break; - } case INTENT_ACTION_LOCK_SCREEN: { handleLockScreen(); break; @@ -383,8 +435,12 @@ public class SystemActions extends SystemUI { handleTakeScreenshot(); break; } - case INTENT_ACTION_ACCESSIBILITY_MENU: { - handleAccessibilityMenu(); + case INTENT_ACTION_ACCESSIBILITY_BUTTON: { + handleAccessibilityButton(); + break; + } + case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER: { + handleAccessibilityButtonChooser(); break; } default: diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java index 251229f42da3..33e6ca49ddd5 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java @@ -84,8 +84,8 @@ public class DisplayUtils { public static int getCornerRadiusBottom(Context context) { int radius = 0; - int resourceId = context.getResources().getIdentifier("rounded_corner_radius_bottom", - "dimen", "android"); + int resourceId = context.getResources().getIdentifier("config_rounded_mask_size_bottom", + "dimen", "com.android.systemui"); if (resourceId > 0) { radius = context.getResources().getDimensionPixelSize(resourceId); } @@ -103,8 +103,8 @@ public class DisplayUtils { public static int getCornerRadiusTop(Context context) { int radius = 0; - int resourceId = context.getResources().getIdentifier("rounded_corner_radius_top", - "dimen", "android"); + int resourceId = context.getResources().getIdentifier("config_rounded_mask_size_top", + "dimen", "com.android.systemui"); if (resourceId > 0) { radius = context.getResources().getDimensionPixelSize(resourceId); } @@ -118,8 +118,8 @@ public class DisplayUtils { private static int getCornerRadiusDefault(Context context) { int radius = 0; - int resourceId = context.getResources().getIdentifier("rounded_corner_radius", "dimen", - "android"); + int resourceId = context.getResources().getIdentifier("config_rounded_mask_size", + "dimen", "com.android.systemui"); if (resourceId > 0) { radius = context.getResources().getDimensionPixelSize(resourceId); } diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java index 2bad7fc9583a..523378e97c94 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java @@ -45,8 +45,8 @@ public final class PathSpecCornerPathRenderer extends CornerPathRenderer { mWidth = DisplayUtils.getWidth(context); mHeight = DisplayUtils.getHeight(context); - mBottomCornerRadius = DisplayUtils.getCornerRadiusBottom(context); - mTopCornerRadius = DisplayUtils.getCornerRadiusTop(context); + mBottomCornerRadius = DisplayUtils.getCornerRadiusBottom(context); + mTopCornerRadius = DisplayUtils.getCornerRadiusTop(context); String pathData = context.getResources().getString(R.string.config_rounded_mask); Path path = PathParser.createPathFromPathData(pathData); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java index e6a62c26712a..95bbea15a88c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java @@ -23,7 +23,7 @@ import android.util.AttributeSet; import android.view.KeyEvent; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; +import android.widget.ImeAwareEditText; import android.widget.TextView; import com.android.internal.widget.LockPatternChecker; @@ -39,7 +39,7 @@ public class AuthCredentialPasswordView extends AuthCredentialView private static final String TAG = "BiometricPrompt/AuthCredentialPasswordView"; private final InputMethodManager mImm; - private EditText mPasswordField; + private ImeAwareEditText mPasswordField; public AuthCredentialPasswordView(Context context, AttributeSet attrs) { @@ -75,11 +75,8 @@ public class AuthCredentialPasswordView extends AuthCredentialView InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD); } - // Wait a bit to focus the field so the focusable flag on the window is already set then. - postDelayed(() -> { - mPasswordField.requestFocus(); - mImm.showSoftInput(mPasswordField, InputMethodManager.SHOW_IMPLICIT); - }, 100); + mPasswordField.requestFocus(); + mPasswordField.scheduleShowSoftInput(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java index 496e60ddf99e..084b791a8dcd 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java @@ -220,15 +220,18 @@ public abstract class AuthCredentialView extends LinearLayout { setTextOrHide(mDescriptionView, getDescription(mBiometricPromptBundle)); announceForAccessibility(title); - final boolean isManagedProfile = Utils.isManagedProfile(mContext, mEffectiveUserId); - final Drawable image; - if (isManagedProfile) { - image = getResources().getDrawable(R.drawable.auth_dialog_enterprise, - mContext.getTheme()); - } else { - image = getResources().getDrawable(R.drawable.auth_dialog_lock, mContext.getTheme()); + if (mIconView != null) { + final boolean isManagedProfile = Utils.isManagedProfile(mContext, mEffectiveUserId); + final Drawable image; + if (isManagedProfile) { + image = getResources().getDrawable(R.drawable.auth_dialog_enterprise, + mContext.getTheme()); + } else { + image = getResources().getDrawable(R.drawable.auth_dialog_lock, + mContext.getTheme()); + } + mIconView.setImageDrawable(image); } - mIconView.setImageDrawable(image); // Only animate this if we're transitioning from a biometric view. if (mShouldAnimateContents) { diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt index 319a6e09d4d1..4269605cef12 100644 --- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt +++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt @@ -60,7 +60,7 @@ private const val DEBUG = true * * Use only for IntentFilters with actions and optionally categories. It does not support, * permissions, schemes, data types, data authorities or priority different than 0. - * Cannot be used for getting sticky broadcasts. + * Cannot be used for getting sticky broadcasts (either as return of registering or as re-delivery). */ @Singleton open class BroadcastDispatcher @Inject constructor ( diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java index 38bfffbb75d9..0dbee663c1c9 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java @@ -78,6 +78,7 @@ class Bubble implements BubbleViewProvider { private BubbleViewInfoTask mInflationTask; private boolean mInflateSynchronously; + private boolean mPendingIntentCanceled; /** * Presentational info about the flyout. @@ -182,6 +183,14 @@ class Bubble implements BubbleViewProvider { mIconView = null; } + void setPendingIntentCanceled() { + mPendingIntentCanceled = true; + } + + boolean getPendingIntentCanceled() { + return mPendingIntentCanceled; + } + /** * Sets whether to perform inflation on the same thread as the caller. This method should only * be used in tests, not in production. @@ -295,6 +304,13 @@ class Bubble implements BubbleViewProvider { } /** + * @return if the bubble was ever expanded + */ + boolean getWasAccessed() { + return mLastAccessed != 0L; + } + + /** * @return the display id of the virtual display on which bubble contents is drawn. */ @Override diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 4d7eb758f733..013f22203fbc 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -171,7 +171,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private INotificationManager mINotificationManager; // Callback that updates BubbleOverflowActivity on data change. - @Nullable private Runnable mOverflowCallback = null; + @Nullable private BubbleData.Listener mOverflowListener = null; private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private IStatusBarService mBarService; @@ -581,8 +581,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mInflateSynchronously = inflateSynchronously; } - void setOverflowCallback(Runnable updateOverflow) { - mOverflowCallback = updateOverflow; + void setOverflowListener(BubbleData.Listener listener) { + mOverflowListener = listener; } /** @@ -669,8 +669,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mStackView.onThemeChanged(); } mBubbleIconFactory = new BubbleIconFactory(mContext); + // Reload each bubble for (Bubble b: mBubbleData.getBubbles()) { - // Reload each bubble + b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory); + } + for (Bubble b: mBubbleData.getOverflowBubbles()) { b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory); } } @@ -815,6 +818,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi return; } bubble.getBubbleIntent().registerCancelListener(pendingIntent -> { + if (bubble.getWasAccessed()) { + bubble.setPendingIntentCanceled(); + return; + } mHandler.post( () -> removeBubble(bubble.getEntry(), BubbleController.DISMISS_INVALID_INTENT)); @@ -959,8 +966,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi @Override public void applyUpdate(BubbleData.Update update) { // Update bubbles in overflow. - if (mOverflowCallback != null) { - mOverflowCallback.run(); + if (mOverflowListener != null) { + mOverflowListener.applyUpdate(update); } // Collapsing? Do this first before remaining steps. @@ -984,7 +991,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (!mBubbleData.hasOverflowBubbleWithKey(bubble.getKey()) && (!bubble.showInShade() || reason == DISMISS_NOTIF_CANCEL - || reason == DISMISS_GROUP_CANCELLED)) { + || reason == DISMISS_GROUP_CANCELLED + || reason == DISMISS_OVERFLOW_MAX_REACHED)) { // The bubble is now gone & the notification is hidden from the shade, so // time to actually remove it for (NotifCallback cb : mCallbacks) { @@ -1051,9 +1059,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi Log.d(TAG, BubbleDebugConfig.formatBubblesString(mStackView.getBubblesOnScreen(), mStackView.getExpandedBubble())); } - Log.d(TAG, "\n[BubbleData] overflow:"); - Log.d(TAG, BubbleDebugConfig.formatBubblesString(mBubbleData.getOverflowBubbles(), - null) + "\n"); } } }; @@ -1236,7 +1241,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi @Override public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask) { + boolean clearedTask, boolean wasVisible) { for (Bubble b : mBubbleData.getBubbles()) { if (b.getDisplayId() == task.displayId) { expandStackAndSelectBubble(b.getKey()); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index 35a4811110a8..f2b1c031dcd5 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -15,6 +15,7 @@ */ package com.android.systemui.bubbles; +import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_DATA; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; @@ -73,6 +74,8 @@ public class BubbleData { @Nullable Bubble selectedBubble; @Nullable Bubble addedBubble; @Nullable Bubble updatedBubble; + @Nullable Bubble addedOverflowBubble; + @Nullable Bubble removedOverflowBubble; // Pair with Bubble and @DismissReason Integer final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); @@ -91,10 +94,12 @@ public class BubbleData { || addedBubble != null || updatedBubble != null || !removedBubbles.isEmpty() + || addedOverflowBubble != null + || removedOverflowBubble != null || orderChanged; } - void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) { + void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) { removedBubbles.add(new Pair<>(bubbleToRemove, reason)); } } @@ -232,6 +237,7 @@ public class BubbleData { private void moveOverflowBubbleToPending(Bubble b) { mOverflowBubbles.remove(b); + mStateChange.removedOverflowBubble = b; mPendingBubbles.add(b); } @@ -439,8 +445,9 @@ public class BubbleData { if (DEBUG_BUBBLE_DATA) { Log.d(TAG, "Cancel overflow bubble: " + b); } - mStateChange.bubbleRemoved(b, reason); mOverflowBubbles.remove(b); + mStateChange.bubbleRemoved(b, reason); + mStateChange.removedOverflowBubble = b; } return; } @@ -473,7 +480,8 @@ public class BubbleData { } void overflowBubble(@DismissReason int reason, Bubble bubble) { - if (!(reason == BubbleController.DISMISS_AGED + if (bubble.getPendingIntentCanceled() + || !(reason == BubbleController.DISMISS_AGED || reason == BubbleController.DISMISS_USER_GESTURE)) { return; } @@ -481,6 +489,7 @@ public class BubbleData { Log.d(TAG, "Overflowing: " + bubble); } mOverflowBubbles.add(0, bubble); + mStateChange.addedOverflowBubble = bubble; bubble.stopInflation(); if (mOverflowBubbles.size() == mMaxOverflowBubbles + 1) { // Remove oldest bubble. @@ -488,8 +497,9 @@ public class BubbleData { if (DEBUG_BUBBLE_DATA) { Log.d(TAG, "Overflow full. Remove: " + oldest); } - mStateChange.bubbleRemoved(oldest, BubbleController.DISMISS_OVERFLOW_MAX_REACHED); mOverflowBubbles.remove(oldest); + mStateChange.removedOverflowBubble = oldest; + mStateChange.bubbleRemoved(oldest, BubbleController.DISMISS_OVERFLOW_MAX_REACHED); } } @@ -772,7 +782,7 @@ public class BubbleData { /** * The set of bubbles in row. */ - @VisibleForTesting(visibility = PRIVATE) + @VisibleForTesting(visibility = PACKAGE) public List<Bubble> getBubbles() { return Collections.unmodifiableList(mBubbles); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java index 37841f24a3cf..de54c353fc85 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java @@ -21,6 +21,7 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; import android.app.Activity; +import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; @@ -60,6 +61,16 @@ public class BubbleOverflowActivity extends Activity { private RecyclerView mRecyclerView; private List<Bubble> mOverflowBubbles = new ArrayList<>(); + private class NoScrollGridLayoutManager extends GridLayoutManager { + NoScrollGridLayoutManager(Context context, int columns) { + super(context, columns); + } + @Override + public boolean canScrollVertically() { + return false; + } + } + @Inject public BubbleOverflowActivity(BubbleController controller) { mBubbleController = controller; @@ -78,7 +89,7 @@ public class BubbleOverflowActivity extends Activity { Resources res = getResources(); final int columns = res.getInteger(R.integer.bubbles_overflow_columns); mRecyclerView.setLayoutManager( - new GridLayoutManager(getApplicationContext(), columns)); + new NoScrollGridLayoutManager(getApplicationContext(), columns)); DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); @@ -95,11 +106,12 @@ public class BubbleOverflowActivity extends Activity { mAdapter = new BubbleOverflowAdapter(mOverflowBubbles, mBubbleController::promoteBubbleFromOverflow, viewWidth, viewHeight); mRecyclerView.setAdapter(mAdapter); - onDataChanged(mBubbleController.getOverflowBubbles()); - mBubbleController.setOverflowCallback(() -> { - onDataChanged(mBubbleController.getOverflowBubbles()); - }); - onThemeChanged(); + + mOverflowBubbles.addAll(mBubbleController.getOverflowBubbles()); + mAdapter.notifyDataSetChanged(); + setEmptyStateVisibility(); + + mBubbleController.setOverflowListener(mDataListener); } /** @@ -126,6 +138,14 @@ public class BubbleOverflowActivity extends Activity { } } + void setEmptyStateVisibility() { + if (mOverflowBubbles.isEmpty()) { + mEmptyState.setVisibility(View.VISIBLE); + } else { + mEmptyState.setVisibility(View.GONE); + } + } + void setBackgroundColor() { final TypedArray ta = getApplicationContext().obtainStyledAttributes( new int[]{android.R.attr.colorBackgroundFloating}); @@ -134,22 +154,40 @@ public class BubbleOverflowActivity extends Activity { findViewById(android.R.id.content).setBackgroundColor(bgColor); } - void onDataChanged(List<Bubble> bubbles) { - mOverflowBubbles.clear(); - mOverflowBubbles.addAll(bubbles); - mAdapter.notifyDataSetChanged(); + private final BubbleData.Listener mDataListener = new BubbleData.Listener() { - if (mOverflowBubbles.isEmpty()) { - mEmptyState.setVisibility(View.VISIBLE); - } else { - mEmptyState.setVisibility(View.GONE); - } + @Override + public void applyUpdate(BubbleData.Update update) { - if (DEBUG_OVERFLOW) { - Log.d(TAG, "Updated overflow bubbles:\n" + BubbleDebugConfig.formatBubblesString( - mOverflowBubbles, /*selected*/ null)); + Bubble toRemove = update.removedOverflowBubble; + if (toRemove != null) { + if (DEBUG_OVERFLOW) { + Log.d(TAG, "remove: " + toRemove); + } + toRemove.cleanupViews(); + int i = mOverflowBubbles.indexOf(toRemove); + mOverflowBubbles.remove(toRemove); + mAdapter.notifyItemRemoved(i); + } + + Bubble toAdd = update.addedOverflowBubble; + if (toAdd != null) { + if (DEBUG_OVERFLOW) { + Log.d(TAG, "add: " + toAdd); + } + mOverflowBubbles.add(0, toAdd); + mAdapter.notifyItemInserted(0); + } + + setEmptyStateVisibility(); + + if (DEBUG_OVERFLOW) { + Log.d(TAG, BubbleDebugConfig.formatBubblesString( + mBubbleController.getOverflowBubbles(), + null)); + } } - } + }; @Override public void onStart() { @@ -215,6 +253,7 @@ class BubbleOverflowAdapter extends RecyclerView.Adapter<BubbleOverflowAdapter.V Bubble b = mBubbles.get(index); vh.iconView.setRenderedBubble(b); + vh.iconView.removeDotSuppressionFlag(BadgedImageView.SuppressionFlag.FLYOUT_VISIBLE); vh.iconView.setOnClickListener(view -> { mBubbles.remove(b); notifyDataSetChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index d870c1191512..366d4a7345af 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -1106,6 +1106,8 @@ public class BubbleStackView extends FrameLayout { // R constants are not final so we cannot use switch-case here. if (action == AccessibilityNodeInfo.ACTION_DISMISS) { mBubbleData.dismissAll(BubbleController.DISMISS_ACCESSIBILITY_ACTION); + announceForAccessibility( + getResources().getString(R.string.accessibility_bubble_dismissed)); return true; } else if (action == AccessibilityNodeInfo.ACTION_COLLAPSE) { mBubbleData.setExpanded(false); @@ -1136,32 +1138,29 @@ public class BubbleStackView extends FrameLayout { if (mBubbleData.getBubbles().isEmpty()) { return; } - Bubble topBubble = mBubbleData.getBubbles().get(0); - String appName = topBubble.getAppName(); - Notification notification = topBubble.getEntry().getSbn().getNotification(); - CharSequence titleCharSeq = notification.extras.getCharSequence(Notification.EXTRA_TITLE); - String titleStr = getResources().getString(R.string.notification_bubble_title); - if (titleCharSeq != null) { - titleStr = titleCharSeq.toString(); - } - int moreCount = mBubbleContainer.getChildCount() - 1; - // Example: Title from app name. - String singleDescription = getResources().getString( - R.string.bubble_content_description_single, titleStr, appName); + for (int i = 0; i < mBubbleData.getBubbles().size(); i++) { + final Bubble bubble = mBubbleData.getBubbles().get(i); + final String appName = bubble.getAppName(); + final Notification notification = bubble.getEntry().getSbn().getNotification(); + final CharSequence titleCharSeq = + notification.extras.getCharSequence(Notification.EXTRA_TITLE); - // Example: Title from app name and 4 more. - String stackDescription = getResources().getString( - R.string.bubble_content_description_stack, titleStr, appName, moreCount); + String titleStr = getResources().getString(R.string.notification_bubble_title); + if (titleCharSeq != null) { + titleStr = titleCharSeq.toString(); + } - if (mIsExpanded) { - // TODO(b/129522932) - update content description for each bubble in expanded view. - } else { - // Collapsed stack. - if (moreCount > 0) { - mBubbleContainer.setContentDescription(stackDescription); - } else { - mBubbleContainer.setContentDescription(singleDescription); + if (bubble.getIconView() != null) { + if (mIsExpanded || i > 0) { + bubble.getIconView().setContentDescription(getResources().getString( + R.string.bubble_content_description_single, titleStr, appName)); + } else { + final int moreCount = mBubbleContainer.getChildCount() - 1; + bubble.getIconView().setContentDescription(getResources().getString( + R.string.bubble_content_description_stack, + titleStr, appName, moreCount)); + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt index 4ca47d1d41ba..cad166d7cd9e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt @@ -76,6 +76,8 @@ object ControlsAnimations { allowEnterTransitionOverlap = true enterTransition = enterWindowTransition(view.getId()) exitTransition = exitWindowTransition(view.getId()) + reenterTransition = enterWindowTransition(view.getId()) + returnTransition = exitWindowTransition(view.getId()) } } @@ -86,6 +88,11 @@ object ControlsAnimations { showAnimation = false } } + + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + fun resetAnimation() { + view.translationY = 0f + } } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt index 640c90d2ba59..4e9c550297c5 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt @@ -16,7 +16,6 @@ package com.android.systemui.controls.management -import android.app.ActivityOptions import android.content.ComponentName import android.content.Intent import android.os.Bundle @@ -70,10 +69,6 @@ class ControlsEditingActivity @Inject constructor( } } - override fun onBackPressed() { - finish() - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -102,6 +97,23 @@ class ControlsEditingActivity @Inject constructor( currentUserTracker.stopTracking() } + override fun onBackPressed() { + globalActionsComponent.handleShowGlobalActionsMenu() + animateExitAndFinish() + } + + private fun animateExitAndFinish() { + val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) + ControlsAnimations.exitAnimation( + rootView, + object : Runnable { + override fun run() { + finish() + } + } + ).start() + } + private fun bindViews() { setContentView(R.layout.controls_management) @@ -124,35 +136,13 @@ class ControlsEditingActivity @Inject constructor( } private fun bindButtons() { - requireViewById<Button>(R.id.other_apps).apply { - visibility = View.VISIBLE - setText(R.string.controls_menu_add) - setOnClickListener { - saveFavorites() - val intent = Intent(this@ControlsEditingActivity, - ControlsFavoritingActivity::class.java).apply { - putExtras(this@ControlsEditingActivity.intent) - putExtra(ControlsFavoritingActivity.EXTRA_SINGLE_STRUCTURE, true) - } - startActivity(intent, ActivityOptions - .makeSceneTransitionAnimation(this@ControlsEditingActivity).toBundle()) - } - } - val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) saveButton = requireViewById<Button>(R.id.done).apply { isEnabled = false setText(R.string.save) setOnClickListener { saveFavorites() - ControlsAnimations.exitAnimation( - rootView, - object : Runnable { - override fun run() { - finish() - } - } - ).start() + animateExitAndFinish() globalActionsComponent.handleShowGlobalActionsMenu() } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index 9a2ccb52132b..e3175aafb1b1 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -16,6 +16,8 @@ package com.android.systemui.controls.management +import android.animation.Animator +import android.animation.AnimatorListenerAdapter import android.app.ActivityOptions import android.content.ComponentName import android.content.Intent @@ -29,6 +31,7 @@ import android.view.ViewStub import android.widget.Button import android.widget.FrameLayout import android.widget.TextView +import android.widget.Toast import androidx.viewpager2.widget.ViewPager2 import com.android.systemui.Prefs import com.android.systemui.R @@ -63,6 +66,7 @@ class ControlsFavoritingActivity @Inject constructor( // If provided, show this structure page first const val EXTRA_STRUCTURE = "extra_structure" const val EXTRA_SINGLE_STRUCTURE = "extra_single_structure" + internal const val EXTRA_FROM_PROVIDER_SELECTOR = "extra_from_provider_selector" private const val TOOLTIP_PREFS_KEY = Prefs.Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT private const val TOOLTIP_MAX_SHOWN = 2 } @@ -70,6 +74,7 @@ class ControlsFavoritingActivity @Inject constructor( private var component: ComponentName? = null private var appName: CharSequence? = null private var structureExtra: CharSequence? = null + private var fromProviderSelector = false private lateinit var structurePager: ViewPager2 private lateinit var statusText: TextView @@ -105,7 +110,10 @@ class ControlsFavoritingActivity @Inject constructor( } override fun onBackPressed() { - finish() + if (!fromProviderSelector) { + globalActionsComponent.handleShowGlobalActionsMenu() + } + animateExitAndFinish() } override fun onCreate(savedInstanceState: Bundle?) { @@ -116,6 +124,7 @@ class ControlsFavoritingActivity @Inject constructor( appName = intent.getCharSequenceExtra(EXTRA_APP) structureExtra = intent.getCharSequenceExtra(EXTRA_STRUCTURE) ?: "" component = intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME) + fromProviderSelector = intent.getBooleanExtra(EXTRA_FROM_PROVIDER_SELECTOR, false) bindViews() } @@ -163,7 +172,23 @@ class ControlsFavoritingActivity @Inject constructor( pageIndicator.visibility = if (listOfStructures.size > 1) View.VISIBLE else View.GONE - ControlsAnimations.enterAnimation(pageIndicator).start() + ControlsAnimations.enterAnimation(pageIndicator).apply { + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + // Position the tooltip if necessary after animations are complete + // so we can get the position on screen. The tooltip is not + // rooted in the layout root. + if (pageIndicator.visibility == View.VISIBLE && + mTooltipManager != null) { + val p = IntArray(2) + pageIndicator.getLocationOnScreen(p) + val x = p[0] + pageIndicator.width / 2 + val y = p[1] + pageIndicator.height + mTooltipManager?.show(R.string.controls_structure_tooltip, x, y) + } + } + }) + }.start() ControlsAnimations.enterAnimation(structurePager).start() } }, Consumer { runnable -> cancelLoadRunnable = runnable }) @@ -225,27 +250,6 @@ class ControlsFavoritingActivity @Inject constructor( } pageIndicator = requireViewById<ManagementPageIndicator>( R.id.structure_page_indicator).apply { - addOnLayoutChangeListener(object : View.OnLayoutChangeListener { - override fun onLayoutChange( - v: View, - left: Int, - top: Int, - right: Int, - bottom: Int, - oldLeft: Int, - oldTop: Int, - oldRight: Int, - oldBottom: Int - ) { - if (v.visibility == View.VISIBLE && mTooltipManager != null) { - val p = IntArray(2) - v.getLocationOnScreen(p) - val x = p[0] + (right - left) / 2 - val y = p[1] + bottom - top - mTooltipManager?.show(R.string.controls_structure_tooltip, x, y) - } - } - }) visibilityListener = { if (it != View.VISIBLE) { mTooltipManager?.hide(true) @@ -271,18 +275,38 @@ class ControlsFavoritingActivity @Inject constructor( bindButtons() } + private fun animateExitAndFinish() { + val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) + ControlsAnimations.exitAnimation( + rootView, + object : Runnable { + override fun run() { + finish() + } + } + ).start() + } + private fun bindButtons() { otherAppsButton = requireViewById<Button>(R.id.other_apps).apply { setOnClickListener { - val i = Intent() - i.setComponent( - ComponentName(context, ControlsProviderSelectorActivity::class.java)) + val i = Intent().apply { + component = ComponentName(context, ControlsProviderSelectorActivity::class.java) + } + if (doneButton.isEnabled) { + // The user has made changes + Toast.makeText( + applicationContext, + R.string.controls_favorite_toast_no_changes, + Toast.LENGTH_SHORT + ).show() + } startActivity(i, ActivityOptions .makeSceneTransitionAnimation(this@ControlsFavoritingActivity).toBundle()) + animateExitAndFinish() } } - val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) doneButton = requireViewById<Button>(R.id.done).apply { isEnabled = false setOnClickListener { @@ -293,15 +317,7 @@ class ControlsFavoritingActivity @Inject constructor( StructureInfo(component!!, it.structureName, favoritesForStorage) ) } - - ControlsAnimations.exitAnimation( - rootView, - object : Runnable { - override fun run() { - finish() - } - } - ).start() + animateExitAndFinish() globalActionsComponent.handleShowGlobalActionsMenu() } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt index 00448544d691..08147746a4c8 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt @@ -34,6 +34,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.controller.ControlsController import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.globalactions.GlobalActionsComponent import com.android.systemui.settings.CurrentUserTracker import com.android.systemui.util.LifecycleActivity import java.util.concurrent.Executor @@ -47,6 +48,7 @@ class ControlsProviderSelectorActivity @Inject constructor( @Background private val backExecutor: Executor, private val listingController: ControlsListingController, private val controlsController: ControlsController, + private val globalActionsComponent: GlobalActionsComponent, broadcastDispatcher: BroadcastDispatcher ) : LifecycleActivity() { @@ -95,12 +97,17 @@ class ControlsProviderSelectorActivity @Inject constructor( visibility = View.VISIBLE setText(com.android.internal.R.string.cancel) setOnClickListener { - this@ControlsProviderSelectorActivity.finishAffinity() + onBackPressed() } } requireViewById<View>(R.id.done).visibility = View.GONE } + override fun onBackPressed() { + globalActionsComponent.handleShowGlobalActionsMenu() + animateExitAndFinish() + } + override fun onStart() { super.onStart() currentUserTracker.startTracking() @@ -144,7 +151,7 @@ class ControlsProviderSelectorActivity @Inject constructor( putExtra(ControlsFavoritingActivity.EXTRA_APP, listingController.getAppLabel(it)) putExtra(Intent.EXTRA_COMPONENT_NAME, it) - flags = Intent.FLAG_ACTIVITY_SINGLE_TOP + putExtra(ControlsFavoritingActivity.EXTRA_FROM_PROVIDER_SELECTOR, true) } startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) } @@ -155,4 +162,16 @@ class ControlsProviderSelectorActivity @Inject constructor( currentUserTracker.stopTracking() super.onDestroy() } + + private fun animateExitAndFinish() { + val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) + ControlsAnimations.exitAnimation( + rootView, + object : Runnable { + override fun run() { + finish() + } + } + ).start() + } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt index a7a41033bb5d..1f07e37d2ad0 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt @@ -47,16 +47,31 @@ object ChallengeDialogs { * [ControlAction#RESPONSE_CHALLENGE_PIN] responses, decided by the useAlphaNumeric * parameter. */ - fun createPinDialog(cvh: ControlViewHolder, useAlphaNumeric: Boolean): Dialog? { + fun createPinDialog( + cvh: ControlViewHolder, + useAlphaNumeric: Boolean, + useRetryStrings: Boolean + ): Dialog? { val lastAction = cvh.lastAction if (lastAction == null) { Log.e(ControlsUiController.TAG, "PIN Dialog attempted but no last action is set. Will not show") return null } + val res = cvh.context.resources + val (title, instructions) = if (useRetryStrings) { + Pair( + res.getString(R.string.controls_pin_wrong), + R.string.controls_pin_instructions_retry + ) + } else { + Pair( + res.getString(R.string.controls_pin_verify, cvh.title.getText()), + R.string.controls_pin_instructions + ) + } val builder = AlertDialog.Builder(cvh.context, STYLE).apply { - val res = cvh.context.resources - setTitle(res.getString(R.string.controls_pin_verify, cvh.title.getText())) + setTitle(title) setView(R.layout.controls_dialog_pin) setPositiveButton( android.R.string.ok, @@ -81,6 +96,7 @@ object ChallengeDialogs { } setOnShowListener(DialogInterface.OnShowListener { _ -> val editText = requireViewById<EditText>(R.id.controls_pin_input) + editText.setHint(instructions) val useAlphaCheckBox = requireViewById<CheckBox>(R.id.controls_pin_use_alpha) useAlphaCheckBox.setChecked(useAlphaNumeric) setInputType(editText, useAlphaCheckBox.isChecked()) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt index 5be2f221ebcb..f5acc287262b 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt @@ -19,6 +19,7 @@ package com.android.systemui.controls.ui import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator +import android.app.Dialog import android.content.Context import android.graphics.drawable.ClipDrawable import android.graphics.drawable.GradientDrawable @@ -58,7 +59,7 @@ class ControlViewHolder( companion object { const val STATE_ANIMATION_DURATION = 700L private const val UPDATE_DELAY_IN_MILLIS = 3000L - private const val ALPHA_ENABLED = (255.0 * 0.2).toInt() + private const val ALPHA_ENABLED = 255 private const val ALPHA_DISABLED = 0 private val FORCE_PANEL_DEVICES = setOf( DeviceTypes.TYPE_THERMOSTAT, @@ -82,6 +83,8 @@ class ControlViewHolder( var cancelUpdate: Runnable? = null var behavior: Behavior? = null var lastAction: ControlAction? = null + private var lastChallengeDialog: Dialog? = null + val deviceType: Int get() = cws.control?.let { it.getDeviceType() } ?: cws.ci.deviceType var dimmed: Boolean = false @@ -140,7 +143,37 @@ class ControlViewHolder( } fun actionResponse(@ControlAction.ResponseResult response: Int) { - // TODO: b/150931809 - handle response codes + // OK responses signal normal behavior, and the app will provide control updates + val failedAttempt = lastChallengeDialog != null + when (response) { + ControlAction.RESPONSE_OK -> + lastChallengeDialog = null + ControlAction.RESPONSE_UNKNOWN -> { + lastChallengeDialog = null + setTransientStatus(context.resources.getString(R.string.controls_error_failed)) + } + ControlAction.RESPONSE_FAIL -> { + lastChallengeDialog = null + setTransientStatus(context.resources.getString(R.string.controls_error_failed)) + } + ControlAction.RESPONSE_CHALLENGE_PIN -> { + lastChallengeDialog = ChallengeDialogs.createPinDialog(this, false, failedAttempt) + lastChallengeDialog?.show() + } + ControlAction.RESPONSE_CHALLENGE_PASSPHRASE -> { + lastChallengeDialog = ChallengeDialogs.createPinDialog(this, true, failedAttempt) + lastChallengeDialog?.show() + } + ControlAction.RESPONSE_CHALLENGE_ACK -> { + lastChallengeDialog = ChallengeDialogs.createConfirmationDialog(this) + lastChallengeDialog?.show() + } + } + } + + fun dismiss() { + lastChallengeDialog?.dismiss() + lastChallengeDialog = null } fun setTransientStatus(tempStatus: String) { @@ -166,7 +199,9 @@ class ControlViewHolder( deviceType: Int ): KClass<out Behavior> { return when { - status == Control.STATUS_UNKNOWN -> UnknownBehavior::class + status == Control.STATUS_UNKNOWN -> StatusBehavior::class + status == Control.STATUS_ERROR -> StatusBehavior::class + status == Control.STATUS_NOT_FOUND -> StatusBehavior::class deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class template is ToggleTemplate -> ToggleBehavior::class template is StatelessTemplate -> TouchBehavior::class diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 42db0051b8e6..25f4940e1f47 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -20,7 +20,6 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ObjectAnimator import android.app.AlertDialog -import android.app.Dialog import android.content.ComponentName import android.content.Context import android.content.DialogInterface @@ -32,7 +31,6 @@ import android.graphics.drawable.LayerDrawable import android.os.Process import android.os.Vibrator import android.service.controls.Control -import android.service.controls.actions.ControlAction import android.util.Log import android.util.TypedValue import android.view.ContextThemeWrapper @@ -101,7 +99,6 @@ class ControlsUiControllerImpl @Inject constructor ( private lateinit var parent: ViewGroup private lateinit var lastItems: List<SelectionItem> private var popup: ListPopupWindow? = null - private var activeDialog: Dialog? = null private var hidden = true private lateinit var dismissGlobalActions: Runnable @@ -170,11 +167,17 @@ class ControlsUiControllerImpl @Inject constructor ( private fun reload(parent: ViewGroup) { if (hidden) return + controlsListingController.get().removeCallback(listingCallback) + controlsController.get().unsubscribe() + val fadeAnim = ObjectAnimator.ofFloat(parent, "alpha", 1.0f, 0.0f) fadeAnim.setInterpolator(AccelerateInterpolator(1.0f)) fadeAnim.setDuration(FADE_IN_MILLIS) fadeAnim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { + controlViewsById.clear() + controlsById.clear() + show(parent, dismissGlobalActions) val showAnim = ObjectAnimator.ofFloat(parent, "alpha", 0.0f, 1.0f) showAnim.setInterpolator(DecelerateInterpolator(1.0f)) @@ -448,21 +451,23 @@ class ControlsUiControllerImpl @Inject constructor ( val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup var lastRow: ViewGroup = createRow(inflater, listView) selectedStructure.controls.forEach { - if (lastRow.getChildCount() == maxColumns) { - lastRow = createRow(inflater, listView) - } - val baseLayout = inflater.inflate( - R.layout.controls_base_item, lastRow, false) as ViewGroup - lastRow.addView(baseLayout) - val cvh = ControlViewHolder( - baseLayout, - controlsController.get(), - uiExecutor, - bgExecutor - ) val key = ControlKey(selectedStructure.componentName, it.controlId) - cvh.bindData(controlsById.getValue(key)) - controlViewsById.put(key, cvh) + controlsById.get(key)?.let { + if (lastRow.getChildCount() == maxColumns) { + lastRow = createRow(inflater, listView) + } + val baseLayout = inflater.inflate( + R.layout.controls_base_item, lastRow, false) as ViewGroup + lastRow.addView(baseLayout) + val cvh = ControlViewHolder( + baseLayout, + controlsController.get(), + uiExecutor, + bgExecutor + ) + cvh.bindData(it) + controlViewsById.put(key, cvh) + } } // add spacers if necessary to keep control size consistent @@ -528,7 +533,6 @@ class ControlsUiControllerImpl @Inject constructor ( if (newSelection != selectedStructure) { selectedStructure = newSelection updatePreferences(selectedStructure) - controlsListingController.get().removeCallback(listingCallback) reload(parent) } } @@ -536,8 +540,12 @@ class ControlsUiControllerImpl @Inject constructor ( override fun hide() { Log.d(ControlsUiController.TAG, "hide()") hidden = true - popup?.dismiss() - activeDialog?.dismiss() + popup?.dismissImmediate() + + controlViewsById.forEach { + it.value.dismiss() + } + ControlActionCoordinator.closeDialog() controlsController.get().unsubscribe() @@ -545,13 +553,13 @@ class ControlsUiControllerImpl @Inject constructor ( parent.removeAllViews() controlsById.clear() controlViewsById.clear() + controlsListingController.get().removeCallback(listingCallback) RenderInfo.clearCache() } override fun onRefreshState(componentName: ComponentName, controls: List<Control>) { - Log.d(ControlsUiController.TAG, "onRefreshState()") controls.forEach { c -> controlsById.get(ControlKey(componentName, c.getControlId()))?.let { Log.d(ControlsUiController.TAG, "onRefreshState() for id: " + c.getControlId()) @@ -569,23 +577,7 @@ class ControlsUiControllerImpl @Inject constructor ( override fun onActionResponse(componentName: ComponentName, controlId: String, response: Int) { val key = ControlKey(componentName, controlId) uiExecutor.execute { - controlViewsById.get(key)?.let { cvh -> - when (response) { - ControlAction.RESPONSE_CHALLENGE_PIN -> { - activeDialog = ChallengeDialogs.createPinDialog(cvh, false) - activeDialog?.show() - } - ControlAction.RESPONSE_CHALLENGE_PASSPHRASE -> { - activeDialog = ChallengeDialogs.createPinDialog(cvh, true) - activeDialog?.show() - } - ControlAction.RESPONSE_CHALLENGE_ACK -> { - activeDialog = ChallengeDialogs.createConfirmationDialog(cvh) - activeDialog?.show() - } - else -> cvh.actionResponse(response) - } - } + controlViewsById.get(key)?.actionResponse(response) } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt index c3572491f9f1..49c44088ce3d 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt @@ -16,7 +16,11 @@ package com.android.systemui.controls.ui -class UnknownBehavior : Behavior { +import android.service.controls.Control + +import com.android.systemui.R + +class StatusBehavior : Behavior { lateinit var cvh: ControlViewHolder override fun initialize(cvh: ControlViewHolder) { @@ -24,7 +28,13 @@ class UnknownBehavior : Behavior { } override fun bind(cws: ControlWithState) { - cvh.status.setText(cvh.context.getString(com.android.internal.R.string.loading)) + val status = cws.control?.status ?: Control.STATUS_UNKNOWN + val msg = when (status) { + Control.STATUS_ERROR -> R.string.controls_error_generic + Control.STATUS_NOT_FOUND -> R.string.controls_error_removed + else -> com.android.internal.R.string.loading + } + cvh.status.setText(cvh.context.getString(msg)) cvh.applyRenderInfo(false) } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java index 3f88f252bfe7..554457b3564a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java @@ -75,6 +75,12 @@ public class DozeDockHandler implements DozeMachine.Part { public void onEvent(int dockState) { if (DEBUG) Log.d(TAG, "dock event = " + dockState); + // Only act upon state changes, otherwise we might overwrite other transitions, + // like proximity sensor initialization. + if (mDockState == dockState) { + return; + } + mDockState = dockState; if (isPulsing()) { return; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index 18bfd899a4e7..490890f263aa 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -159,6 +159,15 @@ public class DozeMachine { mDozeHost = dozeHost; } + /** + * Clean ourselves up. + */ + public void destroy() { + for (Part part : mParts) { + part.destroy(); + } + } + /** Initializes the set of {@link Part}s. Must be called exactly once after construction. */ public void setParts(Part[] parts) { Preconditions.checkState(mParts == null); @@ -411,6 +420,9 @@ public class DozeMachine { /** Dump current state. For debugging only. */ default void dump(PrintWriter pw) {} + + /** Give the Part a chance to clean itself up. */ + default void destroy() {} } /** A wrapper interface for {@link android.service.dreams.DreamService} */ diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 700a8611c8bd..10776c91df84 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -164,6 +164,17 @@ public class DozeSensors { } /** + * Unregister any sensors. + */ + public void destroy() { + // Unregisters everything, which is enough to allow gc. + for (TriggerSensor triggerSensor : mSensors) { + triggerSensor.setListening(false); + } + mProximitySensor.pause(); + } + + /** * Temporarily disable some sensors to avoid turning on the device while the user is * turning it off. */ diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index 7cbbdd783e74..529b016aaca6 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -65,6 +65,7 @@ public class DozeService extends DreamService mPluginManager.removePluginListener(this); } super.onDestroy(); + mDozeMachine.destroy(); mDozeMachine = null; } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index b3299916356c..3510e07d2cea 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -34,6 +34,9 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; +import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -45,6 +48,7 @@ import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.wakelock.WakeLock; import java.io.PrintWriter; +import java.util.Optional; import java.util.function.Consumer; /** @@ -58,6 +62,8 @@ public class DozeTriggers implements DozeMachine.Part { /** adb shell am broadcast -a com.android.systemui.doze.pulse com.android.systemui */ private static final String PULSE_ACTION = "com.android.systemui.doze.pulse"; + private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl(); + /** * Last value sent by the wake-display sensor. * Assuming that the screen should start on. @@ -88,6 +94,62 @@ public class DozeTriggers implements DozeMachine.Part { private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); + @VisibleForTesting + public enum DozingUpdateUiEvent implements UiEventLogger.UiEventEnum { + @UiEvent(doc = "Dozing updated due to notification.") + DOZING_UPDATE_NOTIFICATION(433), + + @UiEvent(doc = "Dozing updated due to sigmotion.") + DOZING_UPDATE_SIGMOTION(434), + + @UiEvent(doc = "Dozing updated because sensor was picked up.") + DOZING_UPDATE_SENSOR_PICKUP(435), + + @UiEvent(doc = "Dozing updated because sensor was double tapped.") + DOZING_UPDATE_SENSOR_DOUBLE_TAP(436), + + @UiEvent(doc = "Dozing updated because sensor was long squeezed.") + DOZING_UPDATE_SENSOR_LONG_SQUEEZE(437), + + @UiEvent(doc = "Dozing updated due to docking.") + DOZING_UPDATE_DOCKING(438), + + @UiEvent(doc = "Dozing updated because sensor woke up.") + DOZING_UPDATE_SENSOR_WAKEUP(439), + + @UiEvent(doc = "Dozing updated because sensor woke up the lockscreen.") + DOZING_UPDATE_SENSOR_WAKE_LOCKSCREEN(440), + + @UiEvent(doc = "Dozing updated because sensor was tapped.") + DOZING_UPDATE_SENSOR_TAP(441); + + private final int mId; + + DozingUpdateUiEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } + + static DozingUpdateUiEvent fromReason(int reason) { + switch (reason) { + case 1: return DOZING_UPDATE_NOTIFICATION; + case 2: return DOZING_UPDATE_SIGMOTION; + case 3: return DOZING_UPDATE_SENSOR_PICKUP; + case 4: return DOZING_UPDATE_SENSOR_DOUBLE_TAP; + case 5: return DOZING_UPDATE_SENSOR_LONG_SQUEEZE; + case 6: return DOZING_UPDATE_DOCKING; + case 7: return DOZING_UPDATE_SENSOR_WAKEUP; + case 8: return DOZING_UPDATE_SENSOR_WAKE_LOCKSCREEN; + case 9: return DOZING_UPDATE_SENSOR_TAP; + default: return null; + } + } + } + public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost, AlarmManager alarmManager, AmbientDisplayConfiguration config, DozeParameters dozeParameters, AsyncSensorManager sensorManager, Handler handler, @@ -111,6 +173,11 @@ public class DozeTriggers implements DozeMachine.Part { mBroadcastDispatcher = broadcastDispatcher; } + @Override + public void destroy() { + mDozeSensors.destroy(); + } + private void onNotification(Runnable onPulseSuppressedListener) { if (DozeMachine.DEBUG) { Log.d(TAG, "requestNotificationPulse"); @@ -219,6 +286,8 @@ public class DozeTriggers implements DozeMachine.Part { mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING) .setType(MetricsEvent.TYPE_UPDATE) .setSubtype(reason)); + Optional.ofNullable(DozingUpdateUiEvent.fromReason(reason)) + .ifPresent(UI_EVENT_LOGGER::log); if (mDozeParameters.getDisplayNeedsBlanking()) { // Let's prepare the display to wake-up by drawing black. // This will cover the hardware wake-up sequence, where the display @@ -396,6 +465,8 @@ public class DozeTriggers implements DozeMachine.Part { // Logs request pulse reason on AOD screen. mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING) .setType(MetricsEvent.TYPE_UPDATE).setSubtype(reason)); + Optional.ofNullable(DozingUpdateUiEvent.fromReason(reason)) + .ifPresent(UI_EVENT_LOGGER::log); } private boolean canPulse() { diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 6aa4f8684928..80ebe5701c3c 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -484,9 +484,16 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, */ @VisibleForTesting protected int getMaxShownPowerItems() { - // TODO: Overflow disabled on keyguard while we solve for touch blocking issues. - if (shouldUseControlsLayout() && !mKeyguardShowing) { - return mResources.getInteger(com.android.systemui.R.integer.power_menu_max_columns); + if (shouldUseControlsLayout()) { + int maxColumns = + mResources.getInteger(com.android.systemui.R.integer.power_menu_max_columns); + // TODO: Overflow temporarily disabled on keyguard to prevent touch issues. + // Show an extra item on the keyguard because the overflow button currently disabled. + if (mKeyguardShowing) { + return maxColumns + 1; + } else { + return maxColumns; + } } else { return Integer.MAX_VALUE; } @@ -609,10 +616,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, getWalletPanelViewController(), mDepthController, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, shouldShowControls() ? mControlsUiController : null, mBlurUtils, - shouldUseControlsLayout(), this::onRotate); + shouldUseControlsLayout(), this::onRotate, mKeyguardShowing); dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. - dialog.setKeyguardShowing(mKeyguardShowing); - dialog.setOnDismissListener(this); dialog.setOnShowListener(this); @@ -1905,7 +1910,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService, NotificationShadeWindowController notificationShadeWindowController, ControlsUiController controlsUiController, BlurUtils blurUtils, - boolean useControlsLayout, Runnable onRotateCallback) { + boolean useControlsLayout, Runnable onRotateCallback, boolean keyguardShowing) { super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions); mContext = context; mAdapter = adapter; @@ -1918,6 +1923,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mBlurUtils = blurUtils; mUseControlsLayout = useControlsLayout; mOnRotateCallback = onRotateCallback; + mKeyguardShowing = keyguardShowing; // Window initialization Window window = getWindow(); @@ -2060,7 +2066,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, View overflowButton = findViewById( com.android.systemui.R.id.global_actions_overflow_button); if (overflowButton != null) { - if (mOverflowAdapter.getCount() > 0) { + // TODO: Overflow button hidden on keyguard to temporarily prevent touch issues. + if (mOverflowAdapter.getCount() > 0 && !mKeyguardShowing) { overflowButton.setOnClickListener((view) -> showPowerOverflowMenu()); LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mGlobalActionsLayout.getLayoutParams(); @@ -2246,7 +2253,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mShowing = false; resetOrientation(); dismissPanel(); - dismissOverflow(); + dismissOverflow(true); if (mControlsUiController != null) mControlsUiController.hide(); mNotificationShadeWindowController.setForceHasTopUi(mHadTopUi); mDepthController.updateGlobalDialogVisibility(0, null /* view */); @@ -2259,9 +2266,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } - private void dismissOverflow() { + private void dismissOverflow(boolean immediate) { if (mOverflowPopup != null) { - mOverflowPopup.dismiss(); + if (immediate) { + mOverflowPopup.dismissImmediate(); + } else { + mOverflowPopup.dismiss(); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 1012a5213a58..b26dc5f91245 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1717,9 +1717,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { resetKeyguardDonePendingLocked(); } - mUpdateMonitor.clearBiometricRecognized(); if (mGoingToSleep) { + mUpdateMonitor.clearBiometricRecognized(); Log.i(TAG, "Device is going to sleep, aborting keyguardDone"); return; } @@ -1740,6 +1740,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { } handleHide(); + mUpdateMonitor.clearBiometricRecognized(); Trace.endSection(); } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 683c7934908b..9509e6d479e3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -19,6 +19,7 @@ package com.android.systemui.media; import android.annotation.LayoutRes; import android.app.PendingIntent; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -35,10 +36,12 @@ import android.media.MediaDescription; import android.media.MediaMetadata; import android.media.ThumbnailUtils; import android.media.session.MediaController; +import android.media.session.MediaController.PlaybackInfo; import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.net.Uri; import android.service.media.MediaBrowserService; +import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -94,6 +97,7 @@ public class MediaControlPanel { public static final String MEDIA_PREFERENCE_KEY = "browser_components"; private SharedPreferences mSharedPrefs; private boolean mCheckedForResumption = false; + private boolean mIsRemotePlayback; // Button IDs used in notifications protected static final int[] NOTIF_ACTION_IDS = { @@ -122,11 +126,7 @@ public class MediaControlPanel { @Override public void onPlaybackStateChanged(PlaybackState state) { final int s = state != null ? state.getState() : PlaybackState.STATE_NONE; - // When the playback state is NONE or CONNECTING, transition the player to the - // resumption state. State CONNECTING needs to be considered for Cast sessions. Ending - // a cast session in YT results in the CONNECTING state, which makes sense if you - // thinking of the session as waiting to connect to another cast device. - if (s == PlaybackState.STATE_NONE || s == PlaybackState.STATE_CONNECTING) { + if (s == PlaybackState.STATE_NONE) { Log.d(TAG, "playback state change will trigger resumption, state=" + state); clearControls(); makeInactive(); @@ -245,7 +245,7 @@ public class MediaControlPanel { // Try to find a browser service component for this app // TODO also check for a media button receiver intended for restarting (b/154127084) // Only check if we haven't tried yet or the session token changed - String pkgName = mController.getPackageName(); + final String pkgName = mController.getPackageName(); if (mServiceComponent == null && !mCheckedForResumption) { Log.d(TAG, "Checking for service component"); PackageManager pm = mContext.getPackageManager(); @@ -281,18 +281,29 @@ public class MediaControlPanel { // Transfer chip mSeamless = mMediaNotifView.findViewById(R.id.media_seamless); - if (mSeamless != null && mLocalMediaManager != null) { - mSeamless.setVisibility(View.VISIBLE); - updateDevice(mLocalMediaManager.getCurrentConnectedDevice()); - mSeamless.setOnClickListener(v -> { - final Intent intent = new Intent() - .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) - .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, - mController.getPackageName()) - .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken); - mActivityStarter.startActivity(intent, false, true /* dismissShade */, - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - }); + if (mSeamless != null) { + if (mLocalMediaManager != null) { + mSeamless.setVisibility(View.VISIBLE); + updateDevice(mLocalMediaManager.getCurrentConnectedDevice()); + mSeamless.setOnClickListener(v -> { + final Intent intent = new Intent() + .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) + .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, + mController.getPackageName()) + .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken); + mActivityStarter.startActivity(intent, false, true /* dismissShade */, + Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + }); + } else { + Log.d(TAG, "LocalMediaManager is null. Not binding output chip for pkg=" + pkgName); + } + } + PlaybackInfo playbackInfo = mController.getPlaybackInfo(); + if (playbackInfo != null) { + mIsRemotePlayback = playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE; + } else { + Log.d(TAG, "PlaybackInfo was null. Defaulting to local playback."); + mIsRemotePlayback = false; } makeActive(); @@ -431,7 +442,7 @@ public class MediaControlPanel { // First look in URI fields for (String field : ART_URIS) { String uriString = metadata.getString(field); - if (uriString != null) { + if (!TextUtils.isEmpty(uriString)) { albumArt = loadBitmapFromUri(Uri.parse(uriString)); if (albumArt != null) { Log.d(TAG, "loaded art from " + field); @@ -459,6 +470,17 @@ public class MediaControlPanel { * @return bitmap, or null if couldn't be loaded */ private Bitmap loadBitmapFromUri(Uri uri) { + // ImageDecoder requires a scheme of the following types + if (uri.getScheme() == null) { + return null; + } + + if (!uri.getScheme().equals(ContentResolver.SCHEME_CONTENT) + && !uri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE) + && !uri.getScheme().equals(ContentResolver.SCHEME_FILE)) { + return null; + } + ImageDecoder.Source source = ImageDecoder.createSource(mContext.getContentResolver(), uri); try { return ImageDecoder.decodeBitmap(source); @@ -528,7 +550,16 @@ public class MediaControlPanel { TextView deviceName = mSeamless.findViewById(R.id.media_seamless_text); deviceName.setTextColor(fgTintList); - if (device != null) { + if (mIsRemotePlayback) { + mSeamless.setEnabled(false); + mSeamless.setAlpha(0.38f); + iconView.setImageResource(R.drawable.ic_hardware_speaker); + iconView.setVisibility(View.VISIBLE); + iconView.setImageTintList(fgTintList); + deviceName.setText(R.string.media_seamless_remote_device); + } else if (device != null) { + mSeamless.setEnabled(true); + mSeamless.setAlpha(1f); Drawable icon = device.getIcon(); iconView.setVisibility(View.VISIBLE); iconView.setImageTintList(fgTintList); @@ -543,6 +574,9 @@ public class MediaControlPanel { deviceName.setText(device.getName()); } else { // Reset to default + Log.d(TAG, "device is null. Not binding output chip."); + mSeamless.setEnabled(true); + mSeamless.setAlpha(1f); iconView.setVisibility(View.GONE); deviceName.setText(com.android.internal.R.string.ext_media_seamless_action); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java index e24d29f1aedf..9d9e74abc38f 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java @@ -126,6 +126,10 @@ public class PipBoundsHandler { mCurrentMinSize = minEdgeSize; } + protected float getAspectRatio() { + return mAspectRatio; + } + /** * Sets both shelf visibility and its height if applicable. * @return {@code true} if the internal shelf state is changed, {@code false} otherwise. @@ -419,7 +423,7 @@ public class PipBoundsHandler { /** * Populates the bounds on the screen that the PIP can be visible in. */ - private void getInsetBounds(Rect outRect) { + protected void getInsetBounds(Rect outRect) { try { mWindowManager.getStableInsets(mContext.getDisplayId(), mTmpInsets); outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 9eae3ca232ff..d38c481752c6 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -250,7 +250,7 @@ public class PipTaskOrganizer extends TaskOrganizer { } @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo info) { + public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) { Objects.requireNonNull(info, "Requires RunningTaskInfo"); final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( info.topActivity, getAspectRatioOrDefault(info.pictureInPictureParams), @@ -259,7 +259,7 @@ public class PipTaskOrganizer extends TaskOrganizer { mTaskInfo = info; mToken = mTaskInfo.token; mInPip = true; - mLeash = mToken.getLeash(); + mLeash = leash; final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); mBoundsToRestore.put(mToken.asBinder(), currentBounds); @@ -285,6 +285,8 @@ public class PipTaskOrganizer extends TaskOrganizer { * Meanwhile this callback is invoked whenever the task is removed. For instance: * - as a result of removeStacksInWindowingModes from WM * - activity itself is died + * Nevertheless, we simply update the internal state here as all the heavy lifting should + * have been done in WM. */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { @@ -297,10 +299,6 @@ public class PipTaskOrganizer extends TaskOrganizer { Log.wtf(TAG, "Unrecognized token: " + token); return; } - final Rect boundsToRestore = mBoundsToRestore.remove(token.asBinder()); - scheduleAnimateResizePip(mLastReportedBounds, boundsToRestore, - TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration, - null /* updateBoundsCallback */); mInPip = false; } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index 78975735ef0f..a86a884c8016 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -135,8 +135,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, - boolean homeTaskVisible, boolean clearedTask) { - if (task.configuration.windowConfiguration.getWindowingMode() + boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { + if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode() != WINDOWING_MODE_PINNED) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index 6c5312d57b2a..fae8af4f575a 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -708,15 +708,15 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mActiveMediaSessionListener, null); updateMediaController(mMediaSessionManager.getActiveSessions(null)); for (int i = mListeners.size() - 1; i >= 0; i--) { - mListeners.get(i).onPipEntered(); + mListeners.get(i).onPipEntered(packageName); } updatePipVisibility(true); } @Override public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask) { - if (task.configuration.windowConfiguration.getWindowingMode() + boolean clearedTask, boolean wasVisible) { + if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode() != WINDOWING_MODE_PINNED) { return; } @@ -758,7 +758,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio * because there's no guarantee for the PIP manager be return relavent information * correctly. (e.g. {@link isPipShown}). */ - void onPipEntered(); + void onPipEntered(String packageName); /** Invoked when a PIPed activity is closed. */ void onPipActivityClosed(); /** Invoked when the PIP menu gets shown. */ diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java index c7e77ccfa488..158be45e0adb 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java @@ -137,8 +137,8 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { } @Override - public void onPipEntered() { - if (DEBUG) Log.d(TAG, "onPipEntered()"); + public void onPipEntered(String packageName) { + if (DEBUG) Log.d(TAG, "onPipEntered(), packageName=" + packageName); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java index b01c2f4eb5fb..30ec29683942 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java @@ -23,6 +23,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.res.Resources; import android.graphics.Bitmap; @@ -50,6 +52,8 @@ public class PipNotification { private static final String ACTION_MENU = "PipNotification.menu"; private static final String ACTION_CLOSE = "PipNotification.close"; + private final PackageManager mPackageManager; + private final PipManager mPipManager; private final NotificationManager mNotificationManager; @@ -59,13 +63,16 @@ public class PipNotification { private String mDefaultTitle; private int mDefaultIconResId; + /** Package name for the application that owns PiP window. */ + private String mPackageName; private boolean mNotified; - private String mTitle; + private String mMediaTitle; private Bitmap mArt; private PipManager.Listener mPipListener = new PipManager.Listener() { @Override - public void onPipEntered() { + public void onPipEntered(String packageName) { + mPackageName = packageName; updateMediaControllerMetadata(); notifyPipNotification(); } @@ -73,6 +80,7 @@ public class PipNotification { @Override public void onPipActivityClosed() { dismissPipNotification(); + mPackageName = null; } @Override @@ -88,6 +96,7 @@ public class PipNotification { @Override public void onMoveToFullscreen() { dismissPipNotification(); + mPackageName = null; } @Override @@ -146,6 +155,8 @@ public class PipNotification { public PipNotification(Context context, BroadcastDispatcher broadcastDispatcher, PipManager pipManager) { + mPackageManager = context.getPackageManager(); + mNotificationManager = (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); @@ -188,7 +199,7 @@ public class PipNotification { .setShowWhen(true) .setWhen(System.currentTimeMillis()) .setSmallIcon(mDefaultIconResId) - .setContentTitle(!TextUtils.isEmpty(mTitle) ? mTitle : mDefaultTitle); + .setContentTitle(getNotificationTitle()); if (mArt != null) { mNotificationBuilder.setStyle(new Notification.BigPictureStyle() .bigPicture(mArt)); @@ -220,14 +231,36 @@ public class PipNotification { } } } - if (!TextUtils.equals(title, mTitle) || art != mArt) { - mTitle = title; + if (!TextUtils.equals(title, mMediaTitle) || art != mArt) { + mMediaTitle = title; mArt = art; return true; } return false; } + private String getNotificationTitle() { + if (!TextUtils.isEmpty(mMediaTitle)) { + return mMediaTitle; + } + + final String applicationTitle = getApplicationLabel(mPackageName); + if (!TextUtils.isEmpty(applicationTitle)) { + return applicationTitle; + } + + return mDefaultTitle; + } + + private String getApplicationLabel(String packageName) { + try { + final ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName, 0); + return mPackageManager.getApplicationLabel(appInfo).toString(); + } catch (PackageManager.NameNotFoundException e) { + return null; + } + } + private static PendingIntent createPendingIntent(Context context, String action) { return PendingIntent.getBroadcast(context, 0, new Intent(action), PendingIntent.FLAG_CANCEL_CURRENT); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java index 302b84203641..9e532868427f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaBrowser.java @@ -82,7 +82,7 @@ public class QSMediaBrowser { public void onChildrenLoaded(String parentId, List<MediaBrowser.MediaItem> children) { if (children.size() == 0) { - Log.e(TAG, "No children found"); + Log.e(TAG, "No children found for " + mComponentName); return; } // We ask apps to return a playable item as the first child when sending diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index c7ce1af0c1fb..121e2aa94954 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -53,6 +53,7 @@ import android.widget.LinearLayout; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.statusbar.NotificationVisibility; import com.android.settingslib.Utils; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.media.InfoMediaManager; @@ -75,6 +76,9 @@ import com.android.systemui.qs.external.CustomTile; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.settings.BrightnessController; import com.android.systemui.settings.ToggleSliderView; +import com.android.systemui.statusbar.notification.NotificationEntryListener; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener; import com.android.systemui.tuner.TunerService; @@ -116,6 +120,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne private final DelayableExecutor mBackgroundExecutor; private boolean mUpdateCarousel = false; private ActivityStarter mActivityStarter; + private NotificationEntryManager mNotificationEntryManager; protected boolean mExpanded; protected boolean mListening; @@ -151,6 +156,15 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne } }; + private final NotificationEntryListener mNotificationEntryListener = + new NotificationEntryListener() { + @Override + public void onEntryRemoved(NotificationEntry entry, NotificationVisibility visibility, + boolean removedByUser, int reason) { + checkToRemoveMediaNotification(entry); + } + }; + @Inject public QSPanel( @Named(VIEW_CONTEXT) Context context, @@ -161,7 +175,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne @Main Executor foregroundExecutor, @Background DelayableExecutor backgroundExecutor, @Nullable LocalBluetoothManager localBluetoothManager, - ActivityStarter activityStarter + ActivityStarter activityStarter, + NotificationEntryManager entryManager ) { super(context, attrs); mContext = context; @@ -172,6 +187,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne mLocalBluetoothManager = localBluetoothManager; mBroadcastDispatcher = broadcastDispatcher; mActivityStarter = activityStarter; + mNotificationEntryManager = entryManager; setOrientation(VERTICAL); @@ -343,6 +359,11 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne return; } + if (desc == null || desc.getTitle() == null) { + Log.e(TAG, "Description incomplete"); + return; + } + Log.d(TAG, "adding track from browser: " + desc + ", " + component); QSMediaPlayer player = new QSMediaPlayer(mContext, QSPanel.this, null, mForegroundExecutor, mBackgroundExecutor, mActivityStarter); @@ -402,6 +423,27 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne mHasLoadedMediaControls = true; } + private void checkToRemoveMediaNotification(NotificationEntry entry) { + if (!useQsMediaPlayer(mContext)) { + return; + } + + if (!entry.isMediaNotification()) { + return; + } + + // If this entry corresponds to an existing set of controls, clear the controls + // This will handle apps that use an action to clear their notification + for (QSMediaPlayer p : mMediaPlayers) { + if (p.getKey() != null && p.getKey().equals(entry.getKey())) { + Log.d(TAG, "Clearing controls since notification removed " + entry.getKey()); + p.clearControls(); + return; + } + } + Log.d(TAG, "Media notification removed but no player found " + entry.getKey()); + } + protected void addDivider() { mDivider = LayoutInflater.from(mContext).inflate(R.layout.qs_divider, this, false); mDivider.setBackgroundColor(Utils.applyAlpha(mDivider.getAlpha(), @@ -468,6 +510,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne loadMediaResumptionControls(); } } + mNotificationEntryManager.addNotificationEntryListener(mNotificationEntryListener); } @Override @@ -484,6 +527,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne } mDumpManager.unregisterDumpable(getDumpableTag()); mBroadcastDispatcher.unregisterReceiver(mUserChangeReceiver); + mNotificationEntryManager.removeNotificationEntryListener(mNotificationEntryListener); super.onDetachedFromWindow(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index becf9da800b3..38dea657242d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -40,6 +40,7 @@ import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.plugins.qs.QSTile.State; import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.qs.logging.QSLogger; +import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.util.Utils; @@ -86,10 +87,12 @@ public class QuickQSPanel extends QSPanel { @Main Executor foregroundExecutor, @Background DelayableExecutor backgroundExecutor, @Nullable LocalBluetoothManager localBluetoothManager, - ActivityStarter activityStarter + ActivityStarter activityStarter, + NotificationEntryManager entryManager ) { super(context, attrs, dumpManager, broadcastDispatcher, qsLogger, - foregroundExecutor, backgroundExecutor, localBluetoothManager, activityStarter); + foregroundExecutor, backgroundExecutor, localBluetoothManager, activityStarter, + entryManager); if (mFooter != null) { removeView(mFooter.getView()); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java index 8051998e2530..f3e2f104621e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java @@ -20,8 +20,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; -import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; - import android.annotation.Nullable; import android.app.ActivityManager; import android.app.trust.TrustManager; @@ -39,7 +37,6 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.phone.StatusBar; @@ -66,22 +63,6 @@ public class OverviewProxyRecentsImpl implements RecentsImplementation { private TrustManager mTrustManager; private OverviewProxyService mOverviewProxyService; - private TaskStackChangeListener mListener = new TaskStackChangeListener() { - @Override - public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, - boolean homeTaskVisible, boolean clearedTask) { - if (task.configuration.windowConfiguration.getWindowingMode() - != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || !mDividerOptional.isPresent()) { - return; - } - - final Divider divider = mDividerOptional.get(); - if (divider.isMinimized()) { - divider.onUndockingTask(); - } - } - }; - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @Inject public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy, @@ -96,7 +77,6 @@ public class OverviewProxyRecentsImpl implements RecentsImplementation { mHandler = new Handler(); mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE); mOverviewProxyService = Dependency.get(OverviewProxyService.class); - ActivityManagerWrapper.getInstance().registerTaskStackListener(mListener); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 70454d4d63df..581422116c8f 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -48,7 +48,6 @@ import android.graphics.Region; import android.graphics.drawable.Icon; import android.media.MediaActionSound; import android.net.Uri; -import android.os.AsyncTask; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -69,6 +68,7 @@ import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.view.WindowManager; +import android.view.animation.AccelerateInterpolator; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.FrameLayout; @@ -83,6 +83,7 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.statusbar.phone.StatusBar; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -163,10 +164,18 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private static final long SCREENSHOT_TO_CORNER_X_DURATION_MS = 234; private static final long SCREENSHOT_TO_CORNER_Y_DURATION_MS = 500; private static final long SCREENSHOT_TO_CORNER_SCALE_DURATION_MS = 234; + private static final long SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS = 400; + private static final long SCREENSHOT_ACTIONS_ALPHA_DURATION_MS = 100; + private static final long SCREENSHOT_DISMISS_Y_DURATION_MS = 350; + private static final long SCREENSHOT_DISMISS_ALPHA_DURATION_MS = 183; + private static final long SCREENSHOT_DISMISS_ALPHA_OFFSET_MS = 50; // delay before starting fade + private static final float SCREENSHOT_ACTIONS_START_SCALE_X = .7f; private static final float ROUNDED_CORNER_RADIUS = .05f; private static final long SCREENSHOT_CORNER_TIMEOUT_MILLIS = 6000; private static final int MESSAGE_CORNER_TIMEOUT = 2; + private final Interpolator mAccelerateInterpolator = new AccelerateInterpolator(); + private final ScreenshotNotificationsController mNotificationsController; private final UiEventLogger mUiEventLogger; @@ -188,16 +197,18 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private final ImageView mDismissImage; private Bitmap mScreenBitmap; + private SaveImageInBackgroundTask mSaveInBgTask; private Animator mScreenshotAnimation; + private Runnable mOnCompleteRunnable; private boolean mInDarkMode = false; + private Animator mDismissAnimation; private float mScreenshotOffsetXPx; private float mScreenshotOffsetYPx; private float mScreenshotHeightPx; private float mDismissButtonSize; private float mCornerSizeX; - - private AsyncTask<Void, Void, Void> mSaveInBgTask; + private float mDismissDeltaY; private MediaActionSound mCameraSound; @@ -210,7 +221,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset switch (msg.what) { case MESSAGE_CORNER_TIMEOUT: mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_INTERACTION_TIMEOUT); - GlobalScreenshot.this.clearScreenshot("timeout"); + GlobalScreenshot.this.dismissScreenshot("timeout", false); + mOnCompleteRunnable.run(); break; default: break; @@ -251,7 +263,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mDismissButton = mScreenshotLayout.findViewById(R.id.global_screenshot_dismiss_button); mDismissButton.setOnClickListener(view -> { mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL); - clearScreenshot("dismiss_button"); + dismissScreenshot("dismiss_button", false); + mOnCompleteRunnable.run(); }); mDismissImage = mDismissButton.findViewById(R.id.global_screenshot_dismiss_image); @@ -262,6 +275,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mScreenshotSelectorView.setFocusableInTouchMode(true); mScreenshotView.setPivotX(0); mScreenshotView.setPivotY(0); + mActionsContainer.setPivotX(0); // Setup the window that we are going to use mWindowLayoutParams = new WindowManager.LayoutParams( @@ -288,6 +302,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mDismissButtonSize = resources.getDimensionPixelSize( R.dimen.screenshot_dismiss_button_tappable_size); mCornerSizeX = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale); + mDismissDeltaY = resources.getDimensionPixelSize(R.dimen.screenshot_dismissal_height_delta); mFastOutSlowIn = AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in); @@ -325,19 +340,19 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset data.finisher = finisher; data.mActionsReadyListener = actionsReadyListener; data.createDeleteAction = false; + if (mSaveInBgTask != null) { - mSaveInBgTask.cancel(false); + mSaveInBgTask.ignoreResult(); } - mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data).execute(); + mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data); + mSaveInBgTask.execute(); } /** * Takes a screenshot of the current display and shows an animation. */ private void takeScreenshot(Consumer<Uri> finisher, Rect crop) { - clearScreenshot("new screenshot requested"); - int rot = mDisplay.getRotation(); int width = crop.width(); int height = crop.height(); @@ -348,11 +363,15 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } private void takeScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect) { + dismissScreenshot("new screenshot requested", true); + mScreenBitmap = screenshot; + if (mScreenBitmap == null) { mNotificationsController.notifyScreenshotError( R.string.screenshot_failed_to_capture_text); finisher.accept(null); + mOnCompleteRunnable.run(); return; } @@ -365,12 +384,17 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this); + if (mDismissAnimation != null && mDismissAnimation.isRunning()) { + mDismissAnimation.cancel(); + } // Start the post-screenshot animation - startAnimation(finisher, screenRect.width(), screenRect.height(), - screenRect); + startAnimation(finisher, screenRect.width(), screenRect.height(), screenRect); } - void takeScreenshot(Consumer<Uri> finisher) { + void takeScreenshot(Consumer<Uri> finisher, Runnable onComplete) { + dismissScreenshot("new screenshot requested", true); + mOnCompleteRunnable = onComplete; + mDisplay.getRealMetrics(mDisplayMetrics); takeScreenshot( finisher, @@ -378,9 +402,10 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } void handleImageAsScreenshot(Bitmap screenshot, Rect screenshotScreenBounds, - Insets visibleInsets, int taskId, Consumer<Uri> finisher) { + Insets visibleInsets, int taskId, Consumer<Uri> finisher, Runnable onComplete) { // TODO use taskId and visibleInsets - clearScreenshot("new screenshot requested"); + dismissScreenshot("new screenshot requested", true); + mOnCompleteRunnable = onComplete; takeScreenshot(screenshot, finisher, screenshotScreenBounds); } @@ -388,7 +413,10 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset * Displays a screenshot selector */ @SuppressLint("ClickableViewAccessibility") - void takeScreenshotPartial(final Consumer<Uri> finisher) { + void takeScreenshotPartial(final Consumer<Uri> finisher, Runnable onComplete) { + dismissScreenshot("new screenshot requested", true); + mOnCompleteRunnable = onComplete; + mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); mScreenshotSelectorView.setOnTouchListener(new View.OnTouchListener() { @Override @@ -439,8 +467,24 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset /** * Clears current screenshot */ - private void clearScreenshot(String reason) { + private void dismissScreenshot(String reason, boolean immediate) { Log.v(TAG, "clearing screenshot: " + reason); + if (!immediate) { + mDismissAnimation = createScreenshotDismissAnimation(); + mDismissAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + clearScreenshot(); + } + }); + mDismissAnimation.start(); + } else { + clearScreenshot(); + } + } + + private void clearScreenshot() { if (mScreenshotLayout.isAttachedToWindow()) { mWindowManager.removeView(mScreenshotLayout); } @@ -457,10 +501,15 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null); mScreenshotView.setContentDescription( mContext.getResources().getString(R.string.screenshot_preview_description)); + mScreenshotLayout.setAlpha(1); + mDismissButton.setTranslationY(0); + mActionsContainer.setTranslationY(0); + mScreenshotView.setTranslationY(0); } /** - * Update assets (called when the dark theme status changes). We only need to update the dismiss + * Update assets (called when the dark theme status changes). We only need to update the + * dismiss * button and the actions container background, since the buttons are re-inflated on demand. */ private void reloadAssets() { @@ -499,13 +548,17 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset */ private void startAnimation(final Consumer<Uri> finisher, int w, int h, @Nullable Rect screenRect) { - // If power save is on, show a toast so there is some visual indication that a screenshot + // If power save is on, show a toast so there is some visual indication that a + // screenshot // has been taken. - PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + PowerManager powerManager = (PowerManager) mContext.getSystemService( + Context.POWER_SERVICE); if (powerManager.isPowerSaveMode()) { - Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show(); + Toast.makeText(mContext, R.string.screenshot_saved_title, + Toast.LENGTH_SHORT).show(); } + // Add the view for the animation mScreenshotView.setImageBitmap(mScreenBitmap); @@ -535,12 +588,12 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } else { createScreenshotActionsShadeAnimation(imageData).start(); } + mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT); + mScreenshotHandler.sendMessageDelayed( + mScreenshotHandler.obtainMessage(MESSAGE_CORNER_TIMEOUT), + SCREENSHOT_CORNER_TIMEOUT_MILLIS); }); } - mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT); - mScreenshotHandler.sendMessageDelayed( - mScreenshotHandler.obtainMessage(MESSAGE_CORNER_TIMEOUT), - SCREENSHOT_CORNER_TIMEOUT_MILLIS); } }); mScreenshotHandler.post(() -> { @@ -571,14 +624,16 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset final PointF startPos = new PointF(bounds.centerX(), bounds.centerY()); final PointF finalPos = new PointF(mScreenshotOffsetXPx + width * cornerScale / 2f, - mDisplayMetrics.heightPixels - mScreenshotOffsetYPx - height * cornerScale / 2f); + mDisplayMetrics.heightPixels - mScreenshotOffsetYPx + - height * cornerScale / 2f); ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1); toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS); float xPositionPct = SCREENSHOT_TO_CORNER_X_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS; float scalePct = - SCREENSHOT_TO_CORNER_SCALE_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS; + SCREENSHOT_TO_CORNER_SCALE_DURATION_MS + / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS; toCorner.addUpdateListener(animation -> { float t = animation.getAnimatedFraction(); if (t < scalePct) { @@ -651,6 +706,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } catch (RemoteException e) { } + ArrayList<ScreenshotActionChip> chips = new ArrayList<>(); + for (Notification.Action smartAction : imageData.smartActions) { ScreenshotActionChip actionChip = (ScreenshotActionChip) inflater.inflate( R.layout.global_screenshot_action_chip, mActionsView, false); @@ -659,9 +716,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset actionChip.setPendingIntent(smartAction.actionIntent, () -> { mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED); - clearScreenshot("chip tapped"); + dismissScreenshot("chip tapped", false); + mOnCompleteRunnable.run(); }); mActionsView.addView(actionChip); + chips.add(actionChip); } ScreenshotActionChip shareChip = (ScreenshotActionChip) inflater.inflate( @@ -670,9 +729,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset shareChip.setIcon(imageData.shareAction.getIcon(), true); shareChip.setPendingIntent(imageData.shareAction.actionIntent, () -> { mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED); - clearScreenshot("chip tapped"); + dismissScreenshot("chip tapped", false); + mOnCompleteRunnable.run(); }); mActionsView.addView(shareChip); + chips.add(shareChip); ScreenshotActionChip editChip = (ScreenshotActionChip) inflater.inflate( R.layout.global_screenshot_action_chip, mActionsView, false); @@ -680,22 +741,24 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset editChip.setIcon(imageData.editAction.getIcon(), true); editChip.setPendingIntent(imageData.editAction.actionIntent, () -> { mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED); - clearScreenshot("chip tapped"); + dismissScreenshot("chip tapped", false); + mOnCompleteRunnable.run(); }); mActionsView.addView(editChip); + chips.add(editChip); mScreenshotView.setOnClickListener(v -> { try { imageData.editAction.actionIntent.send(); mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED); - clearScreenshot("screenshot preview tapped"); + dismissScreenshot("screenshot preview tapped", false); + mOnCompleteRunnable.run(); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Intent cancelled", e); } }); mScreenshotView.setContentDescription(imageData.editAction.title); - if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, SCREENSHOT_SCROLLING_ENABLED, false)) { ScreenshotActionChip scrollChip = (ScreenshotActionChip) inflater.inflate( R.layout.global_screenshot_action_chip, mActionsView, false); @@ -709,22 +772,57 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset scrollNotImplemented.show(); }); mActionsView.addView(scrollChip); + chips.add(scrollChip); } ValueAnimator animator = ValueAnimator.ofFloat(0, 1); - mActionsContainer.setY(mDisplayMetrics.heightPixels); + animator.setDuration(SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS); + float alphaFraction = (float) SCREENSHOT_ACTIONS_ALPHA_DURATION_MS + / SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS; mActionsContainer.setVisibility(VISIBLE); - mActionsContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - float actionsViewHeight = mActionsContainer.getMeasuredHeight() + mScreenshotHeightPx; + mActionsContainer.setAlpha(0); animator.addUpdateListener(animation -> { float t = animation.getAnimatedFraction(); mBackgroundProtection.setAlpha(t); - mActionsContainer.setY(mDisplayMetrics.heightPixels - actionsViewHeight * t); + mActionsContainer.setAlpha(t < alphaFraction ? t / alphaFraction : 1); + float containerScale = SCREENSHOT_ACTIONS_START_SCALE_X + + (t * (1 - SCREENSHOT_ACTIONS_START_SCALE_X)); + mActionsContainer.setScaleX(containerScale); + for (ScreenshotActionChip chip : chips) { + chip.setAlpha(t); + chip.setScaleX(1 / containerScale); // invert to keep size of children constant + } }); return animator; } + private AnimatorSet createScreenshotDismissAnimation() { + ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1); + alphaAnim.setStartDelay(SCREENSHOT_DISMISS_ALPHA_OFFSET_MS); + alphaAnim.setDuration(SCREENSHOT_DISMISS_ALPHA_DURATION_MS); + alphaAnim.addUpdateListener(animation -> { + mScreenshotLayout.setAlpha(1 - animation.getAnimatedFraction()); + }); + + ValueAnimator yAnim = ValueAnimator.ofFloat(0, 1); + yAnim.setInterpolator(mAccelerateInterpolator); + yAnim.setDuration(SCREENSHOT_DISMISS_Y_DURATION_MS); + float screenshotStartY = mScreenshotView.getTranslationY(); + float dismissStartY = mDismissButton.getTranslationY(); + yAnim.addUpdateListener(animation -> { + float yDelta = MathUtils.lerp(0, mDismissDeltaY, animation.getAnimatedFraction()); + mScreenshotView.setTranslationY(screenshotStartY + yDelta); + mDismissButton.setTranslationY(dismissStartY + yDelta); + mActionsContainer.setTranslationY(yDelta); + }); + + AnimatorSet animSet = new AnimatorSet(); + animSet.play(yAnim).with(alphaAnim); + + return animSet; + } + /** * Receiver to proxy the share or edit intent, used to clean up the notification and send * appropriate signals to the system (ie. to dismiss the keyguard if necessary). @@ -770,7 +868,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } if (intent.getBooleanExtra(EXTRA_SMART_ACTIONS_ENABLED, false)) { - String actionType = Intent.ACTION_EDIT.equals(intent.getAction()) ? ACTION_TYPE_EDIT + String actionType = Intent.ACTION_EDIT.equals(intent.getAction()) + ? ACTION_TYPE_EDIT : ACTION_TYPE_SHARE; ScreenshotSmartActions.notifyScreenshotAction( context, intent.getStringExtra(EXTRA_ID), actionType, false); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index 170174deaeb3..bc3c33d68b67 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -130,11 +130,6 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { Resources r = mContext.getResources(); try { - CompletableFuture<List<Notification.Action>> smartActionsFuture = - ScreenshotSmartActions.getSmartActionsFuture( - mScreenshotId, mImageFileName, image, mSmartActionsProvider, - mSmartActionsEnabled, isManagedProfile(mContext)); - // Save the screenshot to the MediaStore final ContentValues values = new ContentValues(); values.put(MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES @@ -148,6 +143,11 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { final Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + CompletableFuture<List<Notification.Action>> smartActionsFuture = + ScreenshotSmartActions.getSmartActionsFuture( + mScreenshotId, uri, image, mSmartActionsProvider, + mSmartActionsEnabled, isManagedProfile(mContext)); + try { // First, write the actual data for our screenshot try (OutputStream out = resolver.openOutputStream(uri)) { @@ -203,7 +203,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { 1000); smartActions.addAll(buildSmartActions( ScreenshotSmartActions.getSmartActions( - mScreenshotId, mImageFileName, smartActionsFuture, timeoutMs, + mScreenshotId, smartActionsFuture, timeoutMs, mSmartActionsProvider), mContext)); } @@ -230,6 +230,19 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { return null; } + /** + * If we get a new screenshot request while this one is saving, we want to continue saving in + * the background but not return anything. + */ + void ignoreResult() { + mParams.mActionsReadyListener = new GlobalScreenshot.ActionsReadyListener() { + @Override + void onActionsReady(GlobalScreenshot.SavedImageData imageData) { + // do nothing + } + }; + } + @Override protected void onCancelled(Void params) { // If we are cancelled while the task is running in the background, we may get null @@ -311,6 +324,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { editIntent.setData(uri); editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // Make sure pending intents for the system user are still unique across users // by setting the (otherwise unused) request code to the current user id. diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java index 09a0644159e2..3edb33da9cd0 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java @@ -19,6 +19,7 @@ package com.android.systemui.screenshot; import android.app.Notification; import android.content.ComponentName; import android.graphics.Bitmap; +import android.net.Uri; import android.util.Log; import java.util.Collections; @@ -67,7 +68,7 @@ public class ScreenshotNotificationSmartActionsProvider { */ public CompletableFuture<List<Notification.Action>> getActions( String screenshotId, - String screenshotFileName, + Uri screenshotUri, Bitmap bitmap, ComponentName componentName, boolean isManagedProfile) { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java index d31344446fac..c228fe2c4334 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java @@ -23,6 +23,7 @@ import android.app.Notification; import android.content.ComponentName; import android.content.Context; import android.graphics.Bitmap; +import android.net.Uri; import android.os.Handler; import android.os.SystemClock; import android.util.Slog; @@ -45,7 +46,7 @@ public class ScreenshotSmartActions { @VisibleForTesting static CompletableFuture<List<Notification.Action>> getSmartActionsFuture( - String screenshotId, String screenshotFileName, Bitmap image, + String screenshotId, Uri screenshotUri, Bitmap image, ScreenshotNotificationSmartActionsProvider smartActionsProvider, boolean smartActionsEnabled, boolean isManagedProfile) { if (!smartActionsEnabled) { @@ -70,7 +71,7 @@ public class ScreenshotSmartActions { ? runningTask.topActivity : new ComponentName("", ""); smartActionsFuture = smartActionsProvider.getActions( - screenshotId, screenshotFileName, image, componentName, isManagedProfile); + screenshotId, screenshotUri, image, componentName, isManagedProfile); } catch (Throwable e) { long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs; smartActionsFuture = CompletableFuture.completedFuture(Collections.emptyList()); @@ -84,7 +85,7 @@ public class ScreenshotSmartActions { } @VisibleForTesting - static List<Notification.Action> getSmartActions(String screenshotId, String screenshotFileName, + static List<Notification.Action> getSmartActions(String screenshotId, CompletableFuture<List<Notification.Action>> smartActionsFuture, int timeoutMs, ScreenshotNotificationSmartActionsProvider smartActionsProvider) { long startTimeMs = SystemClock.uptimeMillis(); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index f68cb745e4c8..98030d45b05e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -16,6 +16,9 @@ package com.android.systemui.screenshot; +import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_PROCESS_COMPLETE; +import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_URI; + import android.app.Service; import android.content.Intent; import android.graphics.Bitmap; @@ -51,8 +54,15 @@ public class TakeScreenshotService extends Service { @Override public void handleMessage(Message msg) { final Messenger callback = msg.replyTo; - Consumer<Uri> finisher = uri -> { - Message reply = Message.obtain(null, 1, uri); + Consumer<Uri> uriConsumer = uri -> { + Message reply = Message.obtain(null, SCREENSHOT_MSG_URI, uri); + try { + callback.send(reply); + } catch (RemoteException e) { + } + }; + Runnable onComplete = () -> { + Message reply = Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE); try { callback.send(reply); } catch (RemoteException e) { @@ -64,7 +74,8 @@ public class TakeScreenshotService extends Service { // animation and error notification. if (!mUserManager.isUserUnlocked()) { Log.w(TAG, "Skipping screenshot because storage is locked!"); - post(() -> finisher.accept(null)); + post(() -> uriConsumer.accept(null)); + post(onComplete); return; } @@ -79,19 +90,19 @@ public class TakeScreenshotService extends Service { switch (msg.what) { case WindowManager.TAKE_SCREENSHOT_FULLSCREEN: if (useCornerFlow) { - mScreenshot.takeScreenshot(finisher); + mScreenshot.takeScreenshot(uriConsumer, onComplete); } else { mScreenshotLegacy.takeScreenshot( - finisher, screenshotRequest.getHasStatusBar(), + uriConsumer, screenshotRequest.getHasStatusBar(), screenshotRequest.getHasNavBar()); } break; case WindowManager.TAKE_SCREENSHOT_SELECTED_REGION: if (useCornerFlow) { - mScreenshot.takeScreenshotPartial(finisher); + mScreenshot.takeScreenshotPartial(uriConsumer, onComplete); } else { mScreenshotLegacy.takeScreenshotPartial( - finisher, screenshotRequest.getHasStatusBar(), + uriConsumer, screenshotRequest.getHasStatusBar(), screenshotRequest.getHasNavBar()); } break; @@ -102,10 +113,10 @@ public class TakeScreenshotService extends Service { int taskId = screenshotRequest.getTaskId(); if (useCornerFlow) { mScreenshot.handleImageAsScreenshot( - screenshot, screenBounds, insets, taskId, finisher); + screenshot, screenBounds, insets, taskId, uriConsumer, onComplete); } else { mScreenshotLegacy.handleImageAsScreenshot( - screenshot, screenBounds, insets, taskId, finisher); + screenshot, screenBounds, insets, taskId, uriConsumer); } break; default: diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index b71c4ebb5930..555202a2b02c 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -21,23 +21,24 @@ import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; +import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Handler; -import android.os.RemoteException; import android.provider.Settings; import android.util.Slog; -import android.window.TaskOrganizer; -import android.window.WindowContainerToken; import android.view.LayoutInflater; import android.view.SurfaceControl; -import android.view.SurfaceSession; import android.view.View; +import android.window.TaskOrganizer; +import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowOrganizer; @@ -48,6 +49,8 @@ import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.TransactionPool; import com.android.systemui.recents.Recents; +import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.wm.DisplayChangeController; import com.android.systemui.wm.DisplayController; @@ -90,7 +93,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, private boolean mHomeStackResizable = false; private ForcedResizableInfoActivityController mForcedResizableController; private SystemWindows mSystemWindows; - final SurfaceSession mSurfaceSession = new SurfaceSession(); private DisplayController mDisplayController; private DisplayImeController mImeController; final TransactionPool mTransactionPool; @@ -259,11 +261,25 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, wct.setScreenSizeDp(mSplits.mSecondary.token, mSplits.mSecondary.configuration.screenWidthDp, mSplits.mSecondary.configuration.screenHeightDp); + + wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mAdjustedPrimary); + adjustAppBounds = new Rect(mSplits.mPrimary.configuration + .windowConfiguration.getAppBounds()); + adjustAppBounds.offset(0, mSplitLayout.mAdjustedPrimary.top + - mSplitLayout.mPrimary.top); + wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds); + wct.setScreenSizeDp(mSplits.mPrimary.token, + mSplits.mPrimary.configuration.screenWidthDp, + mSplits.mPrimary.configuration.screenHeightDp); } else { wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary); wct.setAppBounds(mSplits.mSecondary.token, null); wct.setScreenSizeDp(mSplits.mSecondary.token, SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); + wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mPrimary); + wct.setAppBounds(mSplits.mPrimary.token, null); + wct.setScreenSizeDp(mSplits.mPrimary.token, + SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); } WindowOrganizer.applyTransaction(wct); @@ -415,6 +431,21 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } private final DividerImeController mImePositionProcessor = new DividerImeController(); + private TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() { + @Override + public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, + boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { + if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode() + != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || !mSplits.isSplitScreenSupported()) { + return; + } + + if (isMinimized()) { + onUndockingTask(); + } + } + }; + public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy, DisplayController displayController, SystemWindows systemWindows, DisplayImeController imeController, Handler handler, @@ -474,7 +505,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, return; } try { - mSplits.init(mSurfaceSession); + mSplits.init(); // Set starting tile bounds based on middle target final WindowContainerTransaction tct = new WindowContainerTransaction(); int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position; @@ -485,7 +516,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, removeDivider(); return; } - update(mDisplayController.getDisplayContext(displayId).getResources().getConfiguration()); + ActivityManagerWrapper.getInstance().registerTaskStackListener(mActivityRestartListener); } @Override @@ -554,14 +585,29 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } private void update(Configuration configuration) { + final boolean isDividerHidden = mView != null && mView.isHidden(); + removeDivider(); addDivider(configuration); - if (mMinimized && mView != null) { - mView.setMinimizedDockStack(true, mHomeStackResizable); - updateTouchable(); + + if (mView != null) { + if (mMinimized) { + mView.setMinimizedDockStack(true, mHomeStackResizable); + updateTouchable(); + } + mView.setHidden(isDividerHidden); } } + void onTaskVanished() { + mHandler.post(this::removeDivider); + } + + void onTasksReady() { + mHandler.post(() -> update(mDisplayController.getDisplayContext( + mContext.getDisplayId()).getResources().getConfiguration())); + } + void updateVisibility(final boolean visible) { if (DEBUG) Slog.d(TAG, "Updating visibility " + mVisible + "->" + visible); if (mVisible != visible) { diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java index f5d6cb6fd4b0..717edc591d7f 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java @@ -47,39 +47,27 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { final Divider mDivider; private boolean mSplitScreenSupported = false; + final SurfaceSession mSurfaceSession = new SurfaceSession(); + SplitScreenTaskOrganizer(Divider divider) { mDivider = divider; } - void init(SurfaceSession session) throws RemoteException { + void init() throws RemoteException { registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); - try { - mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, - WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - mSecondary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, - WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); - mPrimarySurface = mPrimary.token.getLeash(); - mSecondarySurface = mSecondary.token.getLeash(); - } catch (Exception e) { - // teardown to prevent callbacks - unregisterOrganizer(); - throw e; + synchronized (this) { + try { + mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, + WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + mSecondary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, + WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + } catch (Exception e) { + // teardown to prevent callbacks + unregisterOrganizer(); + throw e; + } } - mSplitScreenSupported = true; - - // Initialize dim surfaces: - mPrimaryDim = new SurfaceControl.Builder(session).setParent(mPrimarySurface) - .setColorLayer().setName("Primary Divider Dim").build(); - mSecondaryDim = new SurfaceControl.Builder(session).setParent(mSecondarySurface) - .setColorLayer().setName("Secondary Divider Dim").build(); - SurfaceControl.Transaction t = getTransaction(); - t.setLayer(mPrimaryDim, Integer.MAX_VALUE); - t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f}); - t.setLayer(mSecondaryDim, Integer.MAX_VALUE); - t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f}); - t.apply(); - releaseTransaction(t); } boolean isSplitScreenSupported() { @@ -95,6 +83,67 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { } @Override + public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { + synchronized (this) { + if (mPrimary == null || mSecondary == null) { + Log.w(TAG, "Received onTaskAppeared before creating root tasks " + taskInfo); + return; + } + + if (taskInfo.token.equals(mPrimary.token)) { + mPrimarySurface = leash; + } else if (taskInfo.token.equals(mSecondary.token)) { + mSecondarySurface = leash; + } + + if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) { + mSplitScreenSupported = true; + + // Initialize dim surfaces: + mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession) + .setParent(mPrimarySurface).setColorLayer() + .setName("Primary Divider Dim").build(); + mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession) + .setParent(mSecondarySurface).setColorLayer() + .setName("Secondary Divider Dim").build(); + SurfaceControl.Transaction t = getTransaction(); + t.setLayer(mPrimaryDim, Integer.MAX_VALUE); + t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f}); + t.setLayer(mSecondaryDim, Integer.MAX_VALUE); + t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f}); + t.apply(); + releaseTransaction(t); + + mDivider.onTasksReady(); + } + } + } + + @Override + public void onTaskVanished(RunningTaskInfo taskInfo) { + synchronized (this) { + final boolean isPrimaryTask = mPrimary != null + && taskInfo.token.equals(mPrimary.token); + final boolean isSecondaryTask = mSecondary != null + && taskInfo.token.equals(mSecondary.token); + + if (mSplitScreenSupported && (isPrimaryTask || isSecondaryTask)) { + mSplitScreenSupported = false; + + SurfaceControl.Transaction t = getTransaction(); + t.remove(mPrimaryDim); + t.remove(mSecondaryDim); + t.remove(mPrimarySurface); + t.remove(mSecondarySurface); + t.apply(); + releaseTransaction(t); + + mDivider.onTaskVanished(); + } + } + } + + @Override public void onTaskInfoChanged(RunningTaskInfo taskInfo) { if (taskInfo.displayId != DEFAULT_DISPLAY) { return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 12298817d5a6..2647c04ff586 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -19,11 +19,13 @@ import static android.app.Notification.VISIBILITY_SECRET; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static com.android.systemui.DejankUtils.whitelistIpcs; +import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_MEDIA_CONTROLS; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.Notification; +import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -182,7 +184,7 @@ public class NotificationLockscreenUserManagerImpl implements protected final Context mContext; private final Handler mMainHandler; protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>(); - protected final ArrayList<UserInfo> mCurrentManagedProfiles = new ArrayList<>(); + protected final SparseArray<UserInfo> mCurrentManagedProfiles = new SparseArray<>(); protected int mCurrentUserId = 0; protected NotificationPresenter mPresenter; @@ -351,7 +353,10 @@ public class NotificationLockscreenUserManagerImpl implements boolean exceedsPriorityThreshold; if (NotificationUtils.useNewInterruptionModel(mContext) && hideSilentNotificationsOnLockscreen()) { - exceedsPriorityThreshold = entry.getBucket() != BUCKET_SILENT; + exceedsPriorityThreshold = + entry.getBucket() == BUCKET_MEDIA_CONTROLS + || (entry.getBucket() != BUCKET_SILENT + && entry.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT); } else { exceedsPriorityThreshold = !entry.getRanking().isAmbient(); } @@ -425,8 +430,9 @@ public class NotificationLockscreenUserManagerImpl implements */ public boolean allowsManagedPrivateNotificationsInPublic() { synchronized (mLock) { - for (UserInfo profile : mCurrentManagedProfiles) { - if (!userAllowsPrivateNotificationsInPublic(profile.id)) { + for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) { + if (!userAllowsPrivateNotificationsInPublic( + mCurrentManagedProfiles.valueAt(i).id)) { return false; } } @@ -490,15 +496,22 @@ public class NotificationLockscreenUserManagerImpl implements public boolean needsRedaction(NotificationEntry ent) { int userId = ent.getSbn().getUserId(); - boolean currentUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(mCurrentUserId); - boolean notiUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(userId); - boolean redactedLockscreen = currentUserWantsRedaction || notiUserWantsRedaction; + boolean isCurrentUserRedactingNotifs = + !userAllowsPrivateNotificationsInPublic(mCurrentUserId); + boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId); + boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId); + + // redact notifications if the current user is redacting notifications; however if the + // notification is associated with a managed profile, we rely on the managed profile + // setting to determine whether to redact it + boolean isNotifRedacted = (!isNotifForManagedProfile && isCurrentUserRedactingNotifs) + || isNotifUserRedacted; boolean notificationRequestsRedaction = ent.getSbn().getNotification().visibility == Notification.VISIBILITY_PRIVATE; boolean userForcesRedaction = packageHasVisibilityOverride(ent.getSbn().getKey()); - return userForcesRedaction || notificationRequestsRedaction && redactedLockscreen; + return userForcesRedaction || notificationRequestsRedaction && isNotifRedacted; } private boolean packageHasVisibilityOverride(String key) { @@ -519,7 +532,7 @@ public class NotificationLockscreenUserManagerImpl implements for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) { mCurrentProfiles.put(user.id, user); if (UserManager.USER_TYPE_PROFILE_MANAGED.equals(user.userType)) { - mCurrentManagedProfiles.add(user); + mCurrentManagedProfiles.put(user.id, user); } } } @@ -551,7 +564,7 @@ public class NotificationLockscreenUserManagerImpl implements public boolean isAnyManagedProfilePublicMode() { synchronized (mLock) { for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) { - if (isLockscreenPublicMode(mCurrentManagedProfiles.get(i).id)) { + if (isLockscreenPublicMode(mCurrentManagedProfiles.valueAt(i).id)) { return true; } } @@ -668,8 +681,8 @@ public class NotificationLockscreenUserManagerImpl implements } pw.print(" mCurrentManagedProfiles="); synchronized (mLock) { - for (UserInfo userInfo : mCurrentManagedProfiles) { - pw.print("" + userInfo.id + " "); + for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) { + pw.print("" + mCurrentManagedProfiles.valueAt(i).id + " "); } } pw.println(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index 02c41e5aaefe..8fcc67a0708e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -61,7 +61,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle private final Handler mHandler; - /** Re-usable map of notifications to their sorted children.*/ + /** Re-usable map of top-level notifications to their sorted children if any.*/ private final HashMap<NotificationEntry, List<NotificationEntry>> mTmpChildOrderMap = new HashMap<>(); @@ -211,6 +211,8 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle } orderedChildren.add(ent); } else { + // Top-level notif + mTmpChildOrderMap.put(ent, null); toShow.add(ent.getRow()); } } @@ -288,7 +290,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle } - mDynamicChildBindController.updateChildContentViews(mTmpChildOrderMap); + mDynamicChildBindController.updateContentViews(mTmpChildOrderMap); mVisualStabilityManager.onReorderingFinished(); // clear the map again for the next usage mTmpChildOrderMap.clear(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicChildBindController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicChildBindController.java index 148cdea92052..57b41f36e51f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicChildBindController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicChildBindController.java @@ -63,44 +63,52 @@ public class DynamicChildBindController { } /** - * Update the child content views, unbinding content views on children that won't be visible - * and binding content views on children that will be visible eventually. + * Update the content views, unbinding content views on children that won't be visible + * and binding content views on children that will be visible eventually and previously unbound + * children that are no longer children. * - * @param groupNotifs map of notification summaries to their children + * @param groupNotifs map of top-level notifs to their children, if any */ - public void updateChildContentViews( + public void updateContentViews( Map<NotificationEntry, List<NotificationEntry>> groupNotifs) { for (NotificationEntry entry : groupNotifs.keySet()) { List<NotificationEntry> children = groupNotifs.get(entry); + if (children == null) { + if (!hasContent(entry)) { + // Case where child is updated to be top level + bindContent(entry); + } + continue; + } for (int j = 0; j < children.size(); j++) { NotificationEntry childEntry = children.get(j); if (j >= mChildBindCutoff) { - if (hasChildContent(childEntry)) { - freeChildContent(childEntry); + if (hasContent(childEntry)) { + freeContent(childEntry); } } else { - if (!hasChildContent(childEntry)) { - bindChildContent(childEntry); + if (!hasContent(childEntry)) { + bindContent(childEntry); } } } } } - private boolean hasChildContent(NotificationEntry entry) { + private boolean hasContent(NotificationEntry entry) { ExpandableNotificationRow row = entry.getRow(); return row.getPrivateLayout().getContractedChild() != null || row.getPrivateLayout().getExpandedChild() != null; } - private void freeChildContent(NotificationEntry entry) { + private void freeContent(NotificationEntry entry) { RowContentBindParams params = mStage.getStageParams(entry); params.markContentViewsFreeable(FLAG_CONTENT_VIEW_CONTRACTED); params.markContentViewsFreeable(FLAG_CONTENT_VIEW_EXPANDED); mStage.requestRebind(entry, null); } - private void bindChildContent(NotificationEntry entry) { + private void bindContent(NotificationEntry entry) { RowContentBindParams params = mStage.getStageParams(entry); params.requireContentViews(FLAG_CONTENT_VIEW_CONTRACTED); params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java index ba1b23bd80ed..5748c4aa0b13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java @@ -33,6 +33,8 @@ public interface NotificationActivityStarter { void startNotificationGutsIntent(Intent intent, int appUid, ExpandableNotificationRow row); + void startHistoryIntent(boolean showHistory); + default boolean isCollapsingToShowActivityOverLockscreen() { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java index ff945d15a4ed..1c2a00ed601a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java @@ -26,7 +26,6 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.Slog; -import com.android.systemui.R; import com.android.systemui.statusbar.notification.collection.NotificationEntry; /** @@ -44,32 +43,18 @@ public class NotificationChannelHelper { if (!TextUtils.isEmpty(channel.getConversationId())) { return channel; } - final String conversationId = entry.getSbn().getShortcutId(context); + final String conversationId = entry.getSbn().getShortcutId(); final String pkg = entry.getSbn().getPackageName(); final int appUid = entry.getSbn().getUid(); - if (TextUtils.isEmpty(conversationId) || TextUtils.isEmpty(pkg)) { + if (TextUtils.isEmpty(conversationId) || TextUtils.isEmpty(pkg) + || entry.getRanking().getShortcutInfo() == null) { return channel; } - String name; - if (entry.getRanking().getShortcutInfo() != null) { - name = entry.getRanking().getShortcutInfo().getShortLabel().toString(); - } else { - Bundle extras = entry.getSbn().getNotification().extras; - String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE); - if (TextUtils.isEmpty(nameString)) { - nameString = extras.getString(Notification.EXTRA_TITLE); - } - name = nameString; - } - // If this channel is not already a customized conversation channel, create // a custom channel try { - // TODO: When shortcuts are enforced remove this and use the shortcut label for naming - channel.setName(context.getString( - R.string.notification_summary_message_format, - name, channel.getName())); + channel.setName(getName(entry)); notificationManager.createConversationNotificationChannelForPackage( pkg, appUid, entry.getSbn().getKey(), channel, conversationId); @@ -81,4 +66,19 @@ public class NotificationChannelHelper { } return channel; } + + private static String getName(NotificationEntry entry) { + if (entry.getRanking().getShortcutInfo().getShortLabel() != null) { + return entry.getRanking().getShortcutInfo().getShortLabel().toString(); + } + Bundle extras = entry.getSbn().getNotification().extras; + String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE); + if (TextUtils.isEmpty(nameString)) { + nameString = extras.getString(Notification.EXTRA_TITLE); + } + if (TextUtils.isEmpty(nameString)) { + nameString = "fallback"; + } + return nameString; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt index ec17f4ed868c..9738bcc69279 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt @@ -34,12 +34,13 @@ import com.android.systemui.statusbar.notification.stack.NotificationSectionsMan import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_HEADS_UP import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT + import com.android.systemui.statusbar.phone.NotificationGroupManager import com.android.systemui.statusbar.policy.HeadsUpManager import dagger.Lazy -import java.util.Comparator -import java.util.Objects +import java.util.Objects; import javax.inject.Inject +import kotlin.Comparator private const val TAG = "NotifRankingManager" @@ -90,19 +91,13 @@ open class NotificationRankingManager @Inject constructor( val aIsHighPriority = a.isHighPriority() val bIsHighPriority = b.isHighPriority() - when { aHeadsUp != bHeadsUp -> if (aHeadsUp) -1 else 1 // Provide consistent ranking with headsUpManager aHeadsUp -> headsUpManager.compare(a, b) - usePeopleFiltering && aPersonType != bPersonType -> when (aPersonType) { - TYPE_IMPORTANT_PERSON -> -1 - TYPE_PERSON -> when (bPersonType) { - TYPE_IMPORTANT_PERSON -> 1 - else -> -1 - } - else -> 1 - } + + usePeopleFiltering && aPersonType != bPersonType -> + peopleNotificationIdentifier.compareTo(aPersonType, bPersonType) // Upsort current media notification. aMedia != bMedia -> if (aMedia) -1 else 1 // Upsort PRIORITY_MAX system notifications diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt index 5879c15c2493..d36627fb849d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt @@ -20,6 +20,7 @@ import android.annotation.IntDef import android.service.notification.NotificationListenerService.Ranking import android.service.notification.StatusBarNotification import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.PeopleNotificationType +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON @@ -33,21 +34,28 @@ interface PeopleNotificationIdentifier { /** * Identifies if the given notification can be classified as a "People" notification. * - * @return [TYPE_NON_PERSON] if not a people notification, [TYPE_PERSON] if a standard people - * notification, and [TYPE_IMPORTANT_PERSON] if an "important" people notification. + * @return [TYPE_NON_PERSON] if not a people notification, [TYPE_PERSON] if it is a people + * notification that doesn't use shortcuts, [TYPE_FULL_PERSON] if it is a person notification + * that users shortcuts, and [TYPE_IMPORTANT_PERSON] if an "important" people notification + * that users shortcuts. */ @PeopleNotificationType fun getPeopleNotificationType(sbn: StatusBarNotification, ranking: Ranking): Int + fun compareTo(@PeopleNotificationType a: Int, + @PeopleNotificationType b: Int): Int + companion object { @Retention(AnnotationRetention.SOURCE) - @IntDef(prefix = ["TYPE_"], value = [TYPE_NON_PERSON, TYPE_PERSON, TYPE_IMPORTANT_PERSON]) + @IntDef(prefix = ["TYPE_"], value = [TYPE_NON_PERSON, TYPE_PERSON, TYPE_FULL_PERSON, + TYPE_IMPORTANT_PERSON]) annotation class PeopleNotificationType const val TYPE_NON_PERSON = 0 const val TYPE_PERSON = 1 - const val TYPE_IMPORTANT_PERSON = 2 + const val TYPE_FULL_PERSON = 2 + const val TYPE_IMPORTANT_PERSON = 3 } } @@ -69,6 +77,11 @@ class PeopleNotificationIdentifierImpl @Inject constructor( } } + override fun compareTo(@PeopleNotificationType a: Int, + @PeopleNotificationType b: Int): Int { + return b.compareTo(a); + } + /** * Given two [PeopleNotificationType]s, determine the upper bound. Used to constrain a * notification to a type given multiple signals, i.e. notification groups, where each child @@ -84,8 +97,9 @@ class PeopleNotificationIdentifierImpl @Inject constructor( private val Ranking.personTypeInfo get() = when { !isConversation -> TYPE_NON_PERSON + shortcutInfo == null -> TYPE_PERSON channel?.isImportantConversation == true -> TYPE_IMPORTANT_PERSON - else -> TYPE_PERSON + else -> TYPE_FULL_PERSON } private fun extractPersonTypeInfo(sbn: StatusBarNotification) = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index ba72e2879f14..f8844c715230 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -535,6 +535,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return isNonblockable; } + private boolean isConversation() { + return mPeopleNotificationIdentifier + .getPeopleNotificationType(mEntry.getSbn(), mEntry.getRanking()) + != PeopleNotificationIdentifier.TYPE_NON_PERSON; + } + public void onNotificationUpdated() { for (NotificationContentView l : mLayouts) { l.onNotificationUpdated(mEntry); @@ -547,7 +553,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mMenuRow.setAppName(mAppName); } if (mIsSummaryWithChildren) { - mChildrenContainer.recreateNotificationHeader(mExpandClickListener); + mChildrenContainer.recreateNotificationHeader(mExpandClickListener, isConversation()); mChildrenContainer.onNotificationUpdated(); } if (mIconAnimationRunning) { @@ -1135,6 +1141,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (mMenuRow.shouldUseDefaultMenuItems()) { ArrayList<MenuItem> items = new ArrayList<>(); items.add(NotificationMenuRow.createConversationItem(mContext)); + items.add(NotificationMenuRow.createPartialConversationItem(mContext)); items.add(NotificationMenuRow.createInfoItem(mContext)); items.add(NotificationMenuRow.createSnoozeItem(mContext)); items.add(NotificationMenuRow.createAppOpsItem(mContext)); @@ -1831,6 +1838,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } public void resetTranslation() { + if (mMenuRow != null && mMenuRow.isMenuVisible()) { + return; + } + if (mTranslateAnim != null) { mTranslateAnim.cancel(); } @@ -2349,8 +2360,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mIsSummaryWithChildren = mChildrenContainer != null && mChildrenContainer.getNotificationChildCount() > 0; if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() == null) { - mChildrenContainer.recreateNotificationHeader(mExpandClickListener - ); + mChildrenContainer.recreateNotificationHeader(mExpandClickListener, isConversation()); } getShowingLayout().updateBackgroundColor(false /* animate */); mPrivateLayout.updateExpandButtons(isExpandable()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java new file mode 100644 index 000000000000..32477a6f39b7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row; + +import android.annotation.Nullable; +import android.content.Context; +import android.graphics.drawable.Icon; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.internal.widget.ConversationLayout; +import com.android.systemui.R; + +/** + * A hybrid view which may contain information about one ore more conversations. + */ +public class HybridConversationNotificationView extends HybridNotificationView { + + private ImageView mConversationIconView; + private TextView mConversationSenderName; + private View mConversationFacePile; + private int mConversationIconSize; + private int mFacePileSize; + private int mFacePileProtectionWidth; + + public HybridConversationNotificationView(Context context) { + this(context, null); + } + + public HybridConversationNotificationView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public HybridConversationNotificationView( + Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public HybridConversationNotificationView( + Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mConversationIconView = requireViewById(com.android.internal.R.id.conversation_icon); + mConversationFacePile = requireViewById(com.android.internal.R.id.conversation_face_pile); + mConversationSenderName = requireViewById(R.id.conversation_notification_sender); + mFacePileSize = getResources() + .getDimensionPixelSize(R.dimen.conversation_single_line_face_pile_size); + mConversationIconSize = getResources() + .getDimensionPixelSize(R.dimen.conversation_single_line_avatar_size); + mFacePileProtectionWidth = getResources().getDimensionPixelSize( + R.dimen.conversation_single_line_face_pile_protection_width); + mTransformationHelper.addViewTransformingToSimilar(mConversationIconView); + } + + @Override + public void bind(@Nullable CharSequence title, @Nullable CharSequence text, + @Nullable View contentView) { + if (!(contentView instanceof ConversationLayout)) { + super.bind(title, text, contentView); + return; + } + + ConversationLayout conversationLayout = (ConversationLayout) contentView; + Icon conversationIcon = conversationLayout.getConversationIcon(); + if (conversationIcon != null) { + mConversationFacePile.setVisibility(GONE); + mConversationIconView.setVisibility(VISIBLE); + mConversationIconView.setImageIcon(conversationIcon); + } else { + // If there isn't an icon, generate a "face pile" based on the sender avatars + mConversationIconView.setVisibility(GONE); + mConversationFacePile.setVisibility(VISIBLE); + + mConversationFacePile = + requireViewById(com.android.internal.R.id.conversation_face_pile); + ImageView facePileBottomBg = mConversationFacePile.requireViewById( + com.android.internal.R.id.conversation_face_pile_bottom_background); + ImageView facePileBottom = mConversationFacePile.requireViewById( + com.android.internal.R.id.conversation_face_pile_bottom); + ImageView facePileTop = mConversationFacePile.requireViewById( + com.android.internal.R.id.conversation_face_pile_top); + conversationLayout.bindFacePile(facePileBottomBg, facePileBottom, facePileTop); + setSize(mConversationFacePile, mFacePileSize); + setSize(facePileBottom, mConversationIconSize); + setSize(facePileTop, mConversationIconSize); + setSize(facePileBottomBg, mConversationIconSize + 2 * mFacePileProtectionWidth); + mTransformationHelper.addViewTransformingToSimilar(facePileTop); + mTransformationHelper.addViewTransformingToSimilar(facePileBottom); + mTransformationHelper.addViewTransformingToSimilar(facePileBottomBg); + } + CharSequence conversationTitle = conversationLayout.getConversationTitle(); + if (TextUtils.isEmpty(conversationTitle)) { + conversationTitle = title; + } + if (conversationLayout.isOneToOne()) { + mConversationSenderName.setVisibility(GONE); + } else { + mConversationSenderName.setVisibility(VISIBLE); + mConversationSenderName.setText(conversationLayout.getConversationSenderName()); + } + CharSequence conversationText = conversationLayout.getConversationText(); + if (TextUtils.isEmpty(conversationText)) { + conversationText = text; + } + super.bind(conversationTitle, conversationText, conversationLayout); + } + + private static void setSize(View view, int size) { + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams(); + lp.width = size; + lp.height = size; + view.setLayoutParams(lp); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java index fe819574f3b6..0ccebc130b1d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java @@ -16,18 +16,20 @@ package com.android.systemui.statusbar.notification.row; +import android.annotation.Nullable; import android.app.Notification; import android.content.Context; import android.content.res.Resources; +import android.service.notification.StatusBarNotification; import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import com.android.internal.widget.ConversationLayout; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.NotificationDozeHelper; -import com.android.systemui.statusbar.notification.NotificationUtils; /** * A class managing hybrid groups that include {@link HybridNotificationView} and the notification @@ -36,41 +38,41 @@ import com.android.systemui.statusbar.notification.NotificationUtils; public class HybridGroupManager { private final Context mContext; - private final ViewGroup mParent; private float mOverflowNumberSize; private int mOverflowNumberPadding; private int mOverflowNumberColor; - public HybridGroupManager(Context ctx, ViewGroup parent) { + public HybridGroupManager(Context ctx) { mContext = ctx; - mParent = parent; initDimens(); } public void initDimens() { Resources res = mContext.getResources(); - mOverflowNumberSize = res.getDimensionPixelSize( - R.dimen.group_overflow_number_size); - mOverflowNumberPadding = res.getDimensionPixelSize( - R.dimen.group_overflow_number_padding); + mOverflowNumberSize = res.getDimensionPixelSize(R.dimen.group_overflow_number_size); + mOverflowNumberPadding = res.getDimensionPixelSize(R.dimen.group_overflow_number_padding); } - private HybridNotificationView inflateHybridViewWithStyle(int style) { + private HybridNotificationView inflateHybridViewWithStyle(int style, + View contentView, ViewGroup parent) { LayoutInflater inflater = new ContextThemeWrapper(mContext, style) .getSystemService(LayoutInflater.class); - HybridNotificationView hybrid = (HybridNotificationView) inflater.inflate( - R.layout.hybrid_notification, mParent, false); - mParent.addView(hybrid); + int layout = contentView instanceof ConversationLayout + ? R.layout.hybrid_conversation_notification + : R.layout.hybrid_notification; + HybridNotificationView hybrid = (HybridNotificationView) + inflater.inflate(layout, parent, false); + parent.addView(hybrid); return hybrid; } - private TextView inflateOverflowNumber() { + private TextView inflateOverflowNumber(ViewGroup parent) { LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class); TextView numberView = (TextView) inflater.inflate( - R.layout.hybrid_overflow_number, mParent, false); - mParent.addView(numberView); + R.layout.hybrid_overflow_number, parent, false); + parent.addView(numberView); updateOverFlowNumberColor(numberView); return numberView; } @@ -87,22 +89,26 @@ public class HybridGroupManager { } public HybridNotificationView bindFromNotification(HybridNotificationView reusableView, - Notification notification) { - return bindFromNotificationWithStyle(reusableView, notification, - R.style.HybridNotification); + View contentView, StatusBarNotification notification, + ViewGroup parent) { + return bindFromNotificationWithStyle(reusableView, contentView, notification, + R.style.HybridNotification, parent); } private HybridNotificationView bindFromNotificationWithStyle( - HybridNotificationView reusableView, Notification notification, int style) { + HybridNotificationView reusableView, View contentView, + StatusBarNotification notification, + int style, ViewGroup parent) { if (reusableView == null) { - reusableView = inflateHybridViewWithStyle(style); + reusableView = inflateHybridViewWithStyle(style, contentView, parent); } - CharSequence titleText = resolveTitle(notification); - CharSequence contentText = resolveText(notification); - reusableView.bind(titleText, contentText); + CharSequence titleText = resolveTitle(notification.getNotification()); + CharSequence contentText = resolveText(notification.getNotification()); + reusableView.bind(titleText, contentText, contentView); return reusableView; } + @Nullable private CharSequence resolveText(Notification notification) { CharSequence contentText = notification.extras.getCharSequence(Notification.EXTRA_TEXT); if (contentText == null) { @@ -111,6 +117,7 @@ public class HybridGroupManager { return contentText; } + @Nullable private CharSequence resolveTitle(Notification notification) { CharSequence titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE); if (titleText == null) { @@ -119,9 +126,10 @@ public class HybridGroupManager { return titleText; } - public TextView bindOverflowNumber(TextView reusableView, int number) { + public TextView bindOverflowNumber(TextView reusableView, int number, + ViewGroup parent) { if (reusableView == null) { - reusableView = inflateOverflowNumber(); + reusableView = inflateOverflowNumber(parent); } String text = mContext.getResources().getString( R.string.notification_group_overflow_indicator, number); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java index be25d6377912..207144931c3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java @@ -36,8 +36,7 @@ import com.android.systemui.statusbar.notification.TransformState; public class HybridNotificationView extends AlphaOptimizedLinearLayout implements TransformableView { - private ViewTransformationHelper mTransformationHelper; - + protected final ViewTransformationHelper mTransformationHelper = new ViewTransformationHelper(); protected TextView mTitleView; protected TextView mTextView; @@ -69,9 +68,8 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout @Override protected void onFinishInflate() { super.onFinishInflate(); - mTitleView = (TextView) findViewById(R.id.notification_title); - mTextView = (TextView) findViewById(R.id.notification_text); - mTransformationHelper = new ViewTransformationHelper(); + mTitleView = findViewById(R.id.notification_title); + mTextView = findViewById(R.id.notification_text); mTransformationHelper.setCustomTransformation( new ViewTransformationHelper.CustomTransformation() { @Override @@ -106,11 +104,8 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TEXT, mTextView); } - public void bind(CharSequence title) { - bind(title, null); - } - - public void bind(CharSequence title, CharSequence text) { + public void bind(@Nullable CharSequence title, @Nullable CharSequence text, + @Nullable View contentView) { mTitleView.setText(title); mTitleView.setVisibility(TextUtils.isEmpty(title) ? GONE : VISIBLE); if (TextUtils.isEmpty(text)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index bd1745eaa028..e9849ec84987 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -177,7 +177,7 @@ public class NotificationContentView extends FrameLayout { public NotificationContentView(Context context, AttributeSet attrs) { super(context, attrs); - mHybridGroupManager = new HybridGroupManager(getContext(), this); + mHybridGroupManager = new HybridGroupManager(getContext()); mMediaTransferManager = new MediaTransferManager(getContext()); mSmartReplyConstants = Dependency.get(SmartReplyConstants.class); mSmartReplyController = Dependency.get(SmartReplyController.class); @@ -1163,7 +1163,7 @@ public class NotificationContentView extends FrameLayout { if (mIsChildInGroup) { boolean isNewView = mSingleLineView == null; mSingleLineView = mHybridGroupManager.bindFromNotification( - mSingleLineView, mStatusBarNotification.getNotification()); + mSingleLineView, mContractedChild, mStatusBarNotification, this); if (isNewView) { updateViewVisibility(mVisibleType, VISIBLE_TYPE_SINGLELINE, mSingleLineView, mSingleLineView); @@ -1347,11 +1347,11 @@ public class NotificationContentView extends FrameLayout { if (bubbleButton == null || actionContainer == null) { return; } - boolean isPerson = + boolean isPersonWithShortcut = mPeopleIdentifier.getPeopleNotificationType(entry.getSbn(), entry.getRanking()) - != PeopleNotificationIdentifier.TYPE_NON_PERSON; + >= PeopleNotificationIdentifier.TYPE_FULL_PERSON; boolean showButton = isBubblesEnabled() - && isPerson + && isPersonWithShortcut && entry.getBubbleMetadata() != null; if (showButton) { Drawable d = mContext.getResources().getDrawable(entry.isBubble() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java index 23b911b6f687..863951e655e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java @@ -97,7 +97,6 @@ public class NotificationConversationInfo extends LinearLayout implements private String mDelegatePkg; private NotificationChannel mNotificationChannel; private ShortcutInfo mShortcutInfo; - private String mConversationId; private StatusBarNotification mSbn; @Nullable private Notification.BubbleMetadata mBubbleMetadata; private Context mUserContext; @@ -233,14 +232,10 @@ public class NotificationConversationInfo extends LinearLayout implements mBuilderProvider = builderProvider; mShortcutManager = shortcutManager; - mConversationId = mNotificationChannel.getConversationId(); - if (TextUtils.isEmpty(mNotificationChannel.getConversationId())) { - mConversationId = mSbn.getShortcutId(mContext); - } - if (TextUtils.isEmpty(mConversationId)) { + mShortcutInfo = entry.getRanking().getShortcutInfo(); + if (mShortcutInfo == null) { throw new IllegalArgumentException("Does not have required information"); } - mShortcutInfo = entry.getRanking().getShortcutInfo(); mNotificationChannel = NotificationChannelHelper.createConversationChannelIfNeeded( getContext(), mINotificationManager, entry, mNotificationChannel); @@ -319,31 +314,9 @@ public class NotificationConversationInfo extends LinearLayout implements private void bindIcon(boolean important) { ImageView image = findViewById(R.id.conversation_icon); - if (mShortcutInfo != null) { - image.setImageDrawable(mIconFactory.getConversationDrawable( - mShortcutInfo, mPackageName, mAppUid, - important)); - } else { - if (mSbn.getNotification().extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION, false)) { - // TODO: maybe use a generic group icon, or a composite of recent senders - image.setImageDrawable(mPm.getDefaultActivityIcon()); - } else { - final List<Notification.MessagingStyle.Message> messages = - Notification.MessagingStyle.Message.getMessagesFromBundleArray( - (Parcelable[]) mSbn.getNotification().extras.get( - Notification.EXTRA_MESSAGES)); - - final Notification.MessagingStyle.Message latestMessage = - Notification.MessagingStyle.findLatestIncomingMessage(messages); - Icon personIcon = latestMessage.getSenderPerson().getIcon(); - if (personIcon != null) { - image.setImageIcon(latestMessage.getSenderPerson().getIcon()); - } else { - // TODO: choose something better - image.setImageDrawable(mPm.getDefaultActivityIcon()); - } - } - } + image.setImageDrawable(mIconFactory.getConversationDrawable( + mShortcutInfo, mPackageName, mAppUid, important)); + } private void bindPackage() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 1c808cf90321..75affdf20364 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -252,6 +252,9 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx } else if (gutsView instanceof NotificationConversationInfo) { initializeConversationNotificationInfo( row, (NotificationConversationInfo) gutsView); + } else if (gutsView instanceof PartialConversationInfo) { + initializePartialConversationNotificationInfo(row, + (PartialConversationInfo) gutsView); } return true; } catch (Exception e) { @@ -357,7 +360,47 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx } /** - * Sets up the {@link NotificationConversationInfo} inside the notification row's guts. + * Sets up the {@link PartialConversationInfo} inside the notification row's guts. + * @param row view to set up the guts for + * @param notificationInfoView view to set up/bind within {@code row} + */ + @VisibleForTesting + void initializePartialConversationNotificationInfo( + final ExpandableNotificationRow row, + PartialConversationInfo notificationInfoView) throws Exception { + NotificationGuts guts = row.getGuts(); + StatusBarNotification sbn = row.getEntry().getSbn(); + String packageName = sbn.getPackageName(); + // Settings link is only valid for notifications that specify a non-system user + NotificationInfo.OnSettingsClickListener onSettingsClick = null; + UserHandle userHandle = sbn.getUser(); + PackageManager pmUser = StatusBar.getPackageManagerForUser( + mContext, userHandle.getIdentifier()); + + if (!userHandle.equals(UserHandle.ALL) + || mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) { + onSettingsClick = (View v, NotificationChannel channel, int appUid) -> { + mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_NOTE_INFO); + guts.resetFalsingCheck(); + mOnSettingsClickListener.onSettingsClick(sbn.getKey()); + startAppNotificationSettingsActivity(packageName, appUid, channel, row); + }; + } + + notificationInfoView.bindNotification( + pmUser, + mNotificationManager, + packageName, + row.getEntry().getChannel(), + row.getUniqueChannels(), + row.getEntry(), + onSettingsClick, + mDeviceProvisionedController.isDeviceProvisioned(), + row.getIsNonblockable()); + } + + /** + * Sets up the {@link ConversationInfo} inside the notification row's guts. * @param row view to set up the guts for * @param notificationInfoView view to set up/bind within {@code row} */ @@ -394,7 +437,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx guts.resetFalsingCheck(); mOnSettingsClickListener.onSettingsClick(sbn.getKey()); startAppNotificationSettingsActivity(packageName, appUid, channel, row); - notificationInfoView.closeControls(v, false); }; } ConversationIconFactory iconFactoryLoader = new ConversationIconFactory(mContext, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java index 83a6eb297ab3..5e1e3b255867 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java @@ -268,7 +268,9 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl NotificationEntry entry = mParent.getEntry(); int personNotifType = mPeopleNotificationIdentifier .getPeopleNotificationType(entry.getSbn(), entry.getRanking()); - if (personNotifType != PeopleNotificationIdentifier.TYPE_NON_PERSON) { + if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) { + mInfoItem = createPartialConversationItem(mContext); + } else if (personNotifType >= PeopleNotificationIdentifier.TYPE_FULL_PERSON) { mInfoItem = createConversationItem(mContext); } else { mInfoItem = createInfoItem(mContext); @@ -667,6 +669,16 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl R.drawable.ic_settings); } + static NotificationMenuItem createPartialConversationItem(Context context) { + Resources res = context.getResources(); + String infoDescription = res.getString(R.string.notification_menu_gear_description); + PartialConversationInfo infoContent = + (PartialConversationInfo) LayoutInflater.from(context).inflate( + R.layout.partial_conversation_info, null, false); + return new NotificationMenuItem(context, infoDescription, infoContent, + R.drawable.ic_settings); + } + static NotificationMenuItem createInfoItem(Context context) { Resources res = context.getResources(); String infoDescription = res.getString(R.string.notification_menu_gear_description); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java new file mode 100644 index 000000000000..2189b872da43 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.notification.row; + +import static android.app.Notification.EXTRA_IS_GROUP_CONVERSATION; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; + +import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN; + +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import android.annotation.IntDef; +import android.app.INotificationManager; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationChannelGroup; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; +import android.os.Bundle; +import android.os.Parcelable; +import android.os.RemoteException; +import android.service.notification.StatusBarNotification; +import android.text.TextUtils; +import android.transition.ChangeBounds; +import android.transition.Fade; +import android.transition.TransitionManager; +import android.transition.TransitionSet; +import android.util.AttributeSet; +import android.view.View; +import android.view.accessibility.AccessibilityEvent; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.Dependency; +import com.android.systemui.R; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; + +import java.lang.annotation.Retention; +import java.util.List; +import java.util.Set; + +/** + * The guts of a conversation notification that doesn't use valid shortcuts that is revealed when + * performing a long press. + */ +public class PartialConversationInfo extends LinearLayout implements + NotificationGuts.GutsContent { + private static final String TAG = "PartialConvoGuts"; + + private INotificationManager mINotificationManager; + private PackageManager mPm; + private String mPackageName; + private String mAppName; + private int mAppUid; + private String mDelegatePkg; + private NotificationChannel mNotificationChannel; + private StatusBarNotification mSbn; + private boolean mIsDeviceProvisioned; + private boolean mIsNonBlockable; + private Set<NotificationChannel> mUniqueChannelsInRow; + private Drawable mPkgIcon; + + private @Action int mSelectedAction = -1; + private boolean mPressedApply; + private boolean mPresentingChannelEditorDialog = false; + + private NotificationInfo.OnSettingsClickListener mOnSettingsClickListener; + private NotificationGuts mGutsContainer; + private ChannelEditorDialogController mChannelEditorDialogController; + + @VisibleForTesting + boolean mSkipPost = false; + + @Retention(SOURCE) + @IntDef({ACTION_SETTINGS}) + private @interface Action {} + static final int ACTION_SETTINGS = 5; + + private OnClickListener mOnDone = v -> { + mPressedApply = true; + closeControls(v, true); + }; + + public PartialConversationInfo(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void bindNotification( + PackageManager pm, + INotificationManager iNotificationManager, + String pkg, + NotificationChannel notificationChannel, + Set<NotificationChannel> uniqueChannelsInRow, + NotificationEntry entry, + NotificationInfo.OnSettingsClickListener onSettingsClick, + boolean isDeviceProvisioned, + boolean isNonBlockable) { + mSelectedAction = -1; + mINotificationManager = iNotificationManager; + mPackageName = pkg; + mSbn = entry.getSbn(); + mPm = pm; + mAppName = mPackageName; + mOnSettingsClickListener = onSettingsClick; + mNotificationChannel = notificationChannel; + mAppUid = mSbn.getUid(); + mDelegatePkg = mSbn.getOpPkg(); + mIsDeviceProvisioned = isDeviceProvisioned; + mIsNonBlockable = isNonBlockable; + mChannelEditorDialogController = Dependency.get(ChannelEditorDialogController.class); + mUniqueChannelsInRow = uniqueChannelsInRow; + + bindHeader(); + bindActions(); + + View turnOffButton = findViewById(R.id.turn_off_notifications); + turnOffButton.setOnClickListener(getTurnOffNotificationsClickListener()); + turnOffButton.setVisibility(turnOffButton.hasOnClickListeners() && !mIsNonBlockable + ? VISIBLE : GONE); + + View done = findViewById(R.id.done); + done.setOnClickListener(mOnDone); + } + + private void bindActions() { + final View settingsButton = findViewById(R.id.info); + settingsButton.setOnClickListener(getSettingsOnClickListener()); + settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE); + + TextView msg = findViewById(R.id.non_configurable_text); + msg.setText(getResources().getString(R.string.no_shortcut, mAppName)); + } + + private void bindHeader() { + bindConversationDetails(); + + // Delegate + bindDelegate(); + } + + private OnClickListener getSettingsOnClickListener() { + if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) { + final int appUidF = mAppUid; + return ((View view) -> { + mOnSettingsClickListener.onClick(view, mNotificationChannel, appUidF); + }); + } + return null; + } + + private OnClickListener getTurnOffNotificationsClickListener() { + return ((View view) -> { + if (!mPresentingChannelEditorDialog && mChannelEditorDialogController != null) { + mPresentingChannelEditorDialog = true; + + mChannelEditorDialogController.prepareDialogForApp(mAppName, mPackageName, mAppUid, + mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener); + mChannelEditorDialogController.setOnFinishListener(() -> { + mPresentingChannelEditorDialog = false; + closeControls(this, false); + }); + mChannelEditorDialogController.show(); + } + }); + } + + private void bindConversationDetails() { + final TextView channelName = findViewById(R.id.parent_channel_name); + channelName.setText(mNotificationChannel.getName()); + + bindGroup(); + bindName(); + bindPackage(); + bindIcon(); + } + + private void bindName() { + TextView name = findViewById(R.id.name); + Bundle extras = mSbn.getNotification().extras; + String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE); + if (TextUtils.isEmpty(nameString)) { + nameString = extras.getString(Notification.EXTRA_TITLE); + } + name.setText(nameString); + } + + private void bindIcon() { + ImageView image = findViewById(R.id.conversation_icon); + if (mSbn.getNotification().extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION, false)) { + // TODO: maybe use a generic group icon, or a composite of recent senders + image.setImageDrawable(mPkgIcon); + } else { + final List<Notification.MessagingStyle.Message> messages = + Notification.MessagingStyle.Message.getMessagesFromBundleArray( + (Parcelable[]) mSbn.getNotification().extras.get( + Notification.EXTRA_MESSAGES)); + + final Notification.MessagingStyle.Message latestMessage = + Notification.MessagingStyle.findLatestIncomingMessage(messages); + Icon personIcon = null; + if (latestMessage != null && latestMessage.getSenderPerson() != null) { + personIcon = latestMessage.getSenderPerson().getIcon(); + } + if (personIcon != null) { + image.setImageIcon(latestMessage.getSenderPerson().getIcon()); + } else { + image.setImageDrawable(mPkgIcon); + } + } + } + + private void bindPackage() { + ApplicationInfo info; + try { + info = mPm.getApplicationInfo( + mPackageName, + PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.MATCH_DISABLED_COMPONENTS + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.MATCH_DIRECT_BOOT_AWARE); + if (info != null) { + mAppName = String.valueOf(mPm.getApplicationLabel(info)); + mPkgIcon = mPm.getApplicationIcon(info); + } + } catch (PackageManager.NameNotFoundException e) { + mPkgIcon = mPm.getDefaultActivityIcon(); + } + ((TextView) findViewById(R.id.pkg_name)).setText(mAppName); + } + + private void bindDelegate() { + TextView delegateView = findViewById(R.id.delegate_name); + + if (!TextUtils.equals(mPackageName, mDelegatePkg)) { + // this notification was posted by a delegate! + delegateView.setVisibility(View.VISIBLE); + } else { + delegateView.setVisibility(View.GONE); + } + } + + private void bindGroup() { + // Set group information if this channel has an associated group. + CharSequence groupName = null; + if (mNotificationChannel != null && mNotificationChannel.getGroup() != null) { + try { + final NotificationChannelGroup notificationChannelGroup = + mINotificationManager.getNotificationChannelGroupForPackage( + mNotificationChannel.getGroup(), mPackageName, mAppUid); + if (notificationChannelGroup != null) { + groupName = notificationChannelGroup.getName(); + } + } catch (RemoteException e) { + } + } + TextView groupNameView = findViewById(R.id.group_name); + View groupDivider = findViewById(R.id.group_divider); + if (groupName != null) { + groupNameView.setText(groupName); + groupNameView.setVisibility(VISIBLE); + groupDivider.setVisibility(VISIBLE); + } else { + groupNameView.setVisibility(GONE); + groupDivider.setVisibility(GONE); + } + } + + @Override + public boolean post(Runnable action) { + if (mSkipPost) { + action.run(); + return true; + } else { + return super.post(action); + } + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + } + + @Override + public void onFinishedClosing() { + // TODO: do we need to do anything here? + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + if (mGutsContainer != null && + event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { + if (mGutsContainer.isExposed()) { + event.getText().add(mContext.getString( + R.string.notification_channel_controls_opened_accessibility, mAppName)); + } else { + event.getText().add(mContext.getString( + R.string.notification_channel_controls_closed_accessibility, mAppName)); + } + } + } + + /** + * Closes the controls and commits the updated importance values (indirectly). + * + * <p><b>Note,</b> this will only get called once the view is dismissing. This means that the + * user does not have the ability to undo the action anymore. + */ + @VisibleForTesting + void closeControls(View v, boolean save) { + int[] parentLoc = new int[2]; + int[] targetLoc = new int[2]; + mGutsContainer.getLocationOnScreen(parentLoc); + v.getLocationOnScreen(targetLoc); + final int centerX = v.getWidth() / 2; + final int centerY = v.getHeight() / 2; + final int x = targetLoc[0] - parentLoc[0] + centerX; + final int y = targetLoc[1] - parentLoc[1] + centerY; + mGutsContainer.closeControls(x, y, save, false /* force */); + } + + @Override + public void setGutsParent(NotificationGuts guts) { + mGutsContainer = guts; + } + + @Override + public boolean willBeRemoved() { + return false; + } + + @Override + public boolean shouldBeSaved() { + return mPressedApply; + } + + @Override + public View getContentView() { + return this; + } + + @Override + public boolean handleCloseControls(boolean save, boolean force) { + return false; + } + + @Override + public int getActualHeight() { + return getHeight(); + } + + @VisibleForTesting + public boolean isAnimating() { + return false; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt index 13e7fe5cd6d8..15499b87d56d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt @@ -46,13 +46,13 @@ class NotificationConversationTemplateViewWrapper constructor( ) private val conversationLayout: ConversationLayout = view as ConversationLayout - private lateinit var conversationIcon: CachingIconView + private lateinit var conversationIconView: CachingIconView private lateinit var conversationBadgeBg: View private lateinit var expandButton: View private lateinit var expandButtonContainer: View private lateinit var imageMessageContainer: ViewGroup private lateinit var messagingLinearLayout: MessagingLinearLayout - private lateinit var conversationTitle: View + private lateinit var conversationTitleView: View private lateinit var importanceRing: View private lateinit var appName: View private var facePileBottomBg: View? = null @@ -63,7 +63,7 @@ class NotificationConversationTemplateViewWrapper constructor( messagingLinearLayout = conversationLayout.messagingLinearLayout imageMessageContainer = conversationLayout.imageMessageContainer with(conversationLayout) { - conversationIcon = requireViewById(com.android.internal.R.id.conversation_icon) + conversationIconView = requireViewById(com.android.internal.R.id.conversation_icon) conversationBadgeBg = requireViewById(com.android.internal.R.id.conversation_icon_badge_bg) expandButton = requireViewById(com.android.internal.R.id.expand_button) @@ -71,7 +71,7 @@ class NotificationConversationTemplateViewWrapper constructor( requireViewById(com.android.internal.R.id.expand_button_container) importanceRing = requireViewById(com.android.internal.R.id.conversation_icon_badge_ring) appName = requireViewById(com.android.internal.R.id.app_name_text) - conversationTitle = requireViewById(com.android.internal.R.id.conversation_text) + conversationTitleView = requireViewById(com.android.internal.R.id.conversation_text) facePileTop = findViewById(com.android.internal.R.id.conversation_face_pile_top) facePileBottom = findViewById(com.android.internal.R.id.conversation_face_pile_bottom) facePileBottomBg = @@ -93,7 +93,7 @@ class NotificationConversationTemplateViewWrapper constructor( addTransformedViews( messagingLinearLayout, appName, - conversationTitle) + conversationTitleView) // Let's ignore the image message container since that is transforming as part of the // messages already @@ -124,7 +124,7 @@ class NotificationConversationTemplateViewWrapper constructor( ) addViewsTransformingToSimilar( - conversationIcon, + conversationIconView, conversationBadgeBg, expandButton, importanceRing, @@ -136,29 +136,27 @@ class NotificationConversationTemplateViewWrapper constructor( override fun setShelfIconVisible(visible: Boolean) { if (conversationLayout.isImportantConversation) { - if (conversationIcon.visibility != GONE) { - conversationIcon.setForceHidden(visible); + if (conversationIconView.visibility != GONE) { + conversationIconView.isForceHidden = visible // We don't want the small icon to be hidden by the extended wrapper, as force // hiding the conversationIcon will already do that via its listener. - return; + return } } super.setShelfIconVisible(visible) } - override fun getShelfTransformationTarget(): View? { - if (conversationLayout.isImportantConversation) { - if (conversationIcon.visibility != GONE) { - return conversationIcon - } else { - // A notification with a fallback icon was set to important. Currently - // the transformation doesn't work for these and needs to be fixed. In the meantime - // those are using the icon. - return super.getShelfTransformationTarget(); - } - } - return super.getShelfTransformationTarget() - } + override fun getShelfTransformationTarget(): View? = + if (conversationLayout.isImportantConversation) + if (conversationIconView.visibility != GONE) + conversationIconView + else + // A notification with a fallback icon was set to important. Currently + // the transformation doesn't work for these and needs to be fixed. + // In the meantime those are using the icon. + super.getShelfTransformationTarget() + else + super.getShelfTransformationTarget() override fun setRemoteInputVisible(visible: Boolean) = conversationLayout.showHistoricMessages(visible) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java index e20be2b71939..f8b783113ccb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java @@ -27,11 +27,13 @@ import android.view.View; import android.view.ViewGroup; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.widget.CachingIconView; import com.android.internal.widget.NotificationExpandButton; +import com.android.settingslib.Utils; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.statusbar.TransformableView; @@ -60,12 +62,14 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private NotificationExpandButton mExpandButton; protected NotificationHeaderView mNotificationHeader; private TextView mHeaderText; + private TextView mAppNameText; private ImageView mWorkProfileImage; private View mCameraIcon; private View mMicIcon; private View mOverlayIcon; private View mAppOps; private View mAudiblyAlertedIcon; + private FrameLayout mIconContainer; private boolean mIsLowPriority; private boolean mTransformLowPriorityTitle; @@ -108,8 +112,10 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { } protected void resolveHeaderViews() { + mIconContainer = mView.findViewById(com.android.internal.R.id.header_icon_container); mIcon = mView.findViewById(com.android.internal.R.id.icon); mHeaderText = mView.findViewById(com.android.internal.R.id.header_text); + mAppNameText = mView.findViewById(com.android.internal.R.id.app_name_text); mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button); mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge); mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header); @@ -182,6 +188,61 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { } } + public void applyConversationSkin() { + if (mAppNameText != null) { + mAppNameText.setTextAppearance( + com.android.internal.R.style + .TextAppearance_DeviceDefault_Notification_Conversation_AppName); + ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mAppNameText.getLayoutParams(); + layoutParams.setMarginStart(0); + } + if (mIconContainer != null) { + ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mIconContainer.getLayoutParams(); + layoutParams.width = + mIconContainer.getContext().getResources().getDimensionPixelSize( + com.android.internal.R.dimen.conversation_content_start); + final int marginStart = + mIconContainer.getContext().getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_content_margin_start); + layoutParams.setMarginStart(marginStart * -1); + } + if (mIcon != null) { + ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mIcon.getLayoutParams(); + layoutParams.setMarginEnd(0); + } + } + + public void clearConversationSkin() { + if (mAppNameText != null) { + final int textAppearance = Utils.getThemeAttr( + mAppNameText.getContext(), + com.android.internal.R.attr.notificationHeaderTextAppearance, + com.android.internal.R.style.TextAppearance_DeviceDefault_Notification_Info); + mAppNameText.setTextAppearance(textAppearance); + ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mAppNameText.getLayoutParams(); + final int marginStart = mAppNameText.getContext().getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_header_app_name_margin_start); + layoutParams.setMarginStart(marginStart); + } + if (mIconContainer != null) { + ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mIconContainer.getLayoutParams(); + layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; + layoutParams.setMarginStart(0); + } + if (mIcon != null) { + ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mIcon.getLayoutParams(); + final int marginEnd = mIcon.getContext().getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_header_icon_margin_end); + layoutParams.setMarginEnd(marginEnd); + } + } + /** * Adds the remaining TransformTypes to the TransformHelper. This is done to make sure that each * child is faded automatically and doesn't have to be manually added. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java index 351a3ef46dec..c9b1318feb13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.HybridGroupManager; import com.android.systemui.statusbar.notification.row.HybridNotificationView; +import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; import java.util.ArrayList; @@ -99,6 +100,7 @@ public class NotificationChildrenContainer extends ViewGroup { private boolean mIsLowPriority; private OnClickListener mHeaderClickListener; private ViewGroup mCurrentHeader; + private boolean mIsConversation; private boolean mShowDividersWhenExpanded; private boolean mHideDividersDuringExpand; @@ -122,7 +124,7 @@ public class NotificationChildrenContainer extends ViewGroup { public NotificationChildrenContainer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - mHybridGroupManager = new HybridGroupManager(getContext(), this); + mHybridGroupManager = new HybridGroupManager(getContext()); initDimens(); setClipChildren(false); } @@ -308,8 +310,9 @@ public class NotificationChildrenContainer extends ViewGroup { return mAttachedChildren.size(); } - public void recreateNotificationHeader(OnClickListener listener) { + public void recreateNotificationHeader(OnClickListener listener, boolean isConversation) { mHeaderClickListener = listener; + mIsConversation = isConversation; StatusBarNotification notification = mContainingNotification.getEntry().getSbn(); final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(), notification.getNotification()); @@ -328,7 +331,16 @@ public class NotificationChildrenContainer extends ViewGroup { header.reapply(getContext(), mNotificationHeader); } mNotificationHeaderWrapper.onContentUpdated(mContainingNotification); - recreateLowPriorityHeader(builder); + if (mNotificationHeaderWrapper instanceof NotificationHeaderViewWrapper) { + NotificationHeaderViewWrapper headerWrapper = + (NotificationHeaderViewWrapper) mNotificationHeaderWrapper; + if (isConversation) { + headerWrapper.applyConversationSkin(); + } else { + headerWrapper.clearConversationSkin(); + } + } + recreateLowPriorityHeader(builder, isConversation); updateHeaderVisibility(false /* animate */); updateChildrenHeaderAppearance(); } @@ -338,7 +350,7 @@ public class NotificationChildrenContainer extends ViewGroup { * * @param builder a builder to reuse. Otherwise the builder will be recovered. */ - private void recreateLowPriorityHeader(Notification.Builder builder) { + private void recreateLowPriorityHeader(Notification.Builder builder, boolean isConversation) { RemoteViews header; StatusBarNotification notification = mContainingNotification.getEntry().getSbn(); if (mIsLowPriority) { @@ -362,6 +374,15 @@ public class NotificationChildrenContainer extends ViewGroup { header.reapply(getContext(), mNotificationHeaderLowPriority); } mNotificationHeaderWrapperLowPriority.onContentUpdated(mContainingNotification); + if (mNotificationHeaderWrapper instanceof NotificationHeaderViewWrapper) { + NotificationHeaderViewWrapper headerWrapper = + (NotificationHeaderViewWrapper) mNotificationHeaderWrapper; + if (isConversation) { + headerWrapper.applyConversationSkin(); + } else { + headerWrapper.clearConversationSkin(); + } + } resetHeaderVisibilityIfNeeded(mNotificationHeaderLowPriority, calculateDesiredHeader()); } else { removeView(mNotificationHeaderLowPriority); @@ -378,7 +399,7 @@ public class NotificationChildrenContainer extends ViewGroup { int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(true /* likeCollapsed */); if (mUntruncatedChildCount > maxAllowedVisibleChildren) { int number = mUntruncatedChildCount - maxAllowedVisibleChildren; - mOverflowNumber = mHybridGroupManager.bindOverflowNumber(mOverflowNumber, number); + mOverflowNumber = mHybridGroupManager.bindOverflowNumber(mOverflowNumber, number, this); if (mGroupOverFlowState == null) { mGroupOverFlowState = new ViewState(); mNeverAppliedGroupState = true; @@ -1141,7 +1162,7 @@ public class NotificationChildrenContainer extends ViewGroup { removeView(mNotificationHeaderLowPriority); mNotificationHeaderLowPriority = null; } - recreateNotificationHeader(listener); + recreateNotificationHeader(listener, mIsConversation); initDimens(); for (int i = 0; i < mDividers.size(); i++) { View prevDivider = mDividers.get(i); @@ -1225,7 +1246,7 @@ public class NotificationChildrenContainer extends ViewGroup { public void setIsLowPriority(boolean isLowPriority) { mIsLowPriority = isLowPriority; if (mContainingNotification != null) { /* we're not yet set up yet otherwise */ - recreateLowPriorityHeader(null /* existingBuilder */); + recreateLowPriorityHeader(null /* existingBuilder */, mIsConversation); updateHeaderVisibility(false /* animate */); } if (mUserLocked) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java index c4a720cb659f..09ab1d89473e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java @@ -23,6 +23,7 @@ import android.view.View; import android.view.ViewGroup; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.SimpleNotificationListContainer; @@ -194,4 +195,6 @@ public interface NotificationListContainer extends ExpandableView.OnHeightChange * @param v the item to remove */ void removeListItem(@NonNull NotificationListItem v); + + void setNotificationActivityStarter(NotificationActivityStarter notificationActivityStarter); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 9e19c70abf24..7093dd8b39e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -29,6 +29,7 @@ import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEX import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.app.TaskStackBuilder; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.TimeAnimator; @@ -50,6 +51,7 @@ import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; +import android.os.AsyncTask; import android.os.Bundle; import android.os.ServiceManager; import android.provider.Settings; @@ -117,6 +119,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationUtils; @@ -255,6 +258,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd private final AmbientState mAmbientState; private NotificationGroupManager mGroupManager; + private NotificationActivityStarter mNotificationActivityStarter; private HashSet<ExpandableView> mChildrenToAddAnimated = new HashSet<>(); private ArrayList<View> mAddedHeadsUpChildren = new ArrayList<>(); private ArrayList<ExpandableView> mChildrenToRemoveAnimated = new ArrayList<>(); @@ -5699,6 +5703,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } } + @Override + public void setNotificationActivityStarter( + NotificationActivityStarter notificationActivityStarter) { + mNotificationActivityStarter = notificationActivityStarter; + } + @VisibleForTesting @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) protected void inflateFooterView() { @@ -5709,10 +5719,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd clearNotifications(ROWS_ALL, true /* closeShade */); }); footerView.setManageButtonClickListener(v -> { - Intent intent = footerView.isHistoryShown() ? new Intent( - Settings.ACTION_NOTIFICATION_HISTORY) : new Intent( - Settings.ACTION_NOTIFICATION_SETTINGS); - mStatusBar.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP); + mNotificationActivityStarter.startHistoryIntent(mFooterView.isHistoryShown()); }); setFooterView(footerView); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index 8c9bb6c75828..303a0831b52f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -29,6 +29,9 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; +import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardConstants; @@ -50,6 +53,8 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Map; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -64,6 +69,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp private static final boolean DEBUG_BIO_WAKELOCK = KeyguardConstants.DEBUG_BIOMETRIC_WAKELOCK; private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000; private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock"; + private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl(); @IntDef(prefix = { "MODE_" }, value = { MODE_NONE, @@ -171,6 +177,68 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp } } + @VisibleForTesting + public enum BiometricUiEvent implements UiEventLogger.UiEventEnum { + + @UiEvent(doc = "A biometric event of type fingerprint succeeded.") + BIOMETRIC_FINGERPRINT_SUCCESS(396), + + @UiEvent(doc = "A biometric event of type fingerprint failed.") + BIOMETRIC_FINGERPRINT_FAILURE(397), + + @UiEvent(doc = "A biometric event of type fingerprint errored.") + BIOMETRIC_FINGERPRINT_ERROR(398), + + @UiEvent(doc = "A biometric event of type face unlock succeeded.") + BIOMETRIC_FACE_SUCCESS(399), + + @UiEvent(doc = "A biometric event of type face unlock failed.") + BIOMETRIC_FACE_FAILURE(400), + + @UiEvent(doc = "A biometric event of type face unlock errored.") + BIOMETRIC_FACE_ERROR(401), + + @UiEvent(doc = "A biometric event of type iris succeeded.") + BIOMETRIC_IRIS_SUCCESS(402), + + @UiEvent(doc = "A biometric event of type iris failed.") + BIOMETRIC_IRIS_FAILURE(403), + + @UiEvent(doc = "A biometric event of type iris errored.") + BIOMETRIC_IRIS_ERROR(404); + + private final int mId; + + BiometricUiEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } + + static final Map<BiometricSourceType, BiometricUiEvent> ERROR_EVENT_BY_SOURCE_TYPE = Map.of( + BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_ERROR, + BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_ERROR, + BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_ERROR + ); + + static final Map<BiometricSourceType, BiometricUiEvent> SUCCESS_EVENT_BY_SOURCE_TYPE = + Map.of( + BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_SUCCESS, + BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_SUCCESS, + BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_SUCCESS + ); + + static final Map<BiometricSourceType, BiometricUiEvent> FAILURE_EVENT_BY_SOURCE_TYPE = + Map.of( + BiometricSourceType.FINGERPRINT, BiometricUiEvent.BIOMETRIC_FINGERPRINT_FAILURE, + BiometricSourceType.FACE, BiometricUiEvent.BIOMETRIC_FACE_FAILURE, + BiometricSourceType.IRIS, BiometricUiEvent.BIOMETRIC_IRIS_FAILURE + ); + } + @Inject public BiometricUnlockController(Context context, DozeScrimController dozeScrimController, KeyguardViewMediator keyguardViewMediator, ScrimController scrimController, @@ -274,6 +342,9 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp } mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH) .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType))); + Optional.ofNullable(BiometricUiEvent.SUCCESS_EVENT_BY_SOURCE_TYPE.get(biometricSourceType)) + .ifPresent(UI_EVENT_LOGGER::log); + boolean unlockAllowed = mKeyguardBypassController.onBiometricAuthenticated( biometricSourceType, isStrongBiometric); if (unlockAllowed) { @@ -504,6 +575,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) { mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH) .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType))); + Optional.ofNullable(BiometricUiEvent.FAILURE_EVENT_BY_SOURCE_TYPE.get(biometricSourceType)) + .ifPresent(UI_EVENT_LOGGER::log); cleanup(); } @@ -513,6 +586,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH) .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType)) .addTaggedData(MetricsEvent.FIELD_BIOMETRIC_AUTH_ERROR, msgId)); + Optional.ofNullable(BiometricUiEvent.ERROR_EVENT_BY_SOURCE_TYPE.get(biometricSourceType)) + .ifPresent(UI_EVENT_LOGGER::log); cleanup(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index f9119c7a010f..ba8a63428cf6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -556,7 +556,8 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa private void updateDisabledForQuickstep() { int rotation = mContext.getResources().getConfiguration().windowConfiguration.getRotation(); - mDisabledForQuickstep = mStartingQuickstepRotation != rotation; + mDisabledForQuickstep = mStartingQuickstepRotation > -1 && + mStartingQuickstepRotation != rotation; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java index a19d35ac4e81..ec54b302b055 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -65,7 +65,6 @@ public class LockIcon extends KeyguardAffordanceView { mPredrawRegistered = false; int newState = mState; - mOldState = mState; Drawable icon = getIcon(newState); setImageDrawable(icon, false); @@ -135,6 +134,7 @@ public class LockIcon extends KeyguardAffordanceView { } void update(int newState, boolean pulsing, boolean dozing, boolean keyguardJustShown) { + mOldState = mState; mState = newState; mPulsing = pulsing; mDozing = dozing; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java index a633e1979bad..a2e7306d4931 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java @@ -470,8 +470,10 @@ public class LockscreenLockIconController { } private int getState() { - if ((mKeyguardStateController.canDismissLockScreen() || !mKeyguardShowing - || mKeyguardStateController.isKeyguardGoingAway()) && !mSimLocked) { + if ((mKeyguardStateController.canDismissLockScreen() + || !mKeyguardStateController.isShowing() + || mKeyguardStateController.isKeyguardGoingAway() + || mKeyguardStateController.isKeyguardFadingAway()) && !mSimLocked) { return STATE_LOCK_OPEN; } else if (mTransientBiometricsError) { return STATE_BIOMETRICS_ERROR; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 9ee204ea2e45..b2aa769f1bff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -98,6 +98,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.internal.view.AppearanceRegion; import com.android.systemui.R; +import com.android.systemui.accessibility.SystemActions; import com.android.systemui.assist.AssistHandleViewController; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -185,6 +186,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback private WindowManager mWindowManager; private final CommandQueue mCommandQueue; private long mLastLockToAppLongPress; + private final SystemActions mSystemActions; private Locale mLocale; private int mLayoutDirection; @@ -373,6 +375,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback Optional<Recents> recentsOptional, Lazy<StatusBar> statusBarLazy, ShadeController shadeController, NotificationRemoteInputManager notificationRemoteInputManager, + SystemActions systemActions, @Main Handler mainHandler) { mAccessibilityManagerWrapper = accessibilityManagerWrapper; mDeviceProvisionedController = deviceProvisionedController; @@ -391,6 +394,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mCommandQueue = commandQueue; mDivider = divider; mRecentsOptional = recentsOptional; + mSystemActions = systemActions; mHandler = mainHandler; } @@ -1168,6 +1172,16 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable) .setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isNavBarWindowVisible()) .commitUpdate(mDisplayId); + registerAction(clickable, SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON); + registerAction(longClickable, SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER); + } + + private void registerAction(boolean register, int actionId) { + if (register) { + mSystemActions.register(actionId); + } else { + mSystemActions.unregister(actionId); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 420b75c688ab..ac5557b571d7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -116,6 +116,9 @@ import android.widget.DateTimeView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; +import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.RegisterStatusBarResult; @@ -301,6 +304,8 @@ public class StatusBar extends SystemUI implements DemoMode, /** If true, the lockscreen will show a distinct wallpaper */ public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true; + private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl(); + static { boolean onlyCoreApps; try { @@ -459,6 +464,44 @@ public class StatusBar extends SystemUI implements DemoMode, } }; + @VisibleForTesting + public enum StatusBarUiEvent implements UiEventLogger.UiEventEnum { + @UiEvent(doc = "Secured lockscreen is opened.") + LOCKSCREEN_OPEN_SECURE(405), + + @UiEvent(doc = "Lockscreen without security is opened.") + LOCKSCREEN_OPEN_INSECURE(406), + + @UiEvent(doc = "Secured lockscreen is closed.") + LOCKSCREEN_CLOSE_SECURE(407), + + @UiEvent(doc = "Lockscreen without security is closed.") + LOCKSCREEN_CLOSE_INSECURE(408), + + @UiEvent(doc = "Secured bouncer is opened.") + BOUNCER_OPEN_SECURE(409), + + @UiEvent(doc = "Bouncer without security is opened.") + BOUNCER_OPEN_INSECURE(410), + + @UiEvent(doc = "Secured bouncer is closed.") + BOUNCER_CLOSE_SECURE(411), + + @UiEvent(doc = "Bouncer without security is closed.") + BOUNCER_CLOSE_INSECURE(412); + + private final int mId; + + StatusBarUiEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } + } + protected final H mHandler = createHandler(); private int mInteractingWindows; @@ -1258,6 +1301,9 @@ public class StatusBar extends SystemUI implements DemoMode, .setNotificationPanelViewController(mNotificationPanelViewController) .build(); + ((NotificationListContainer) mStackScroller) + .setNotificationActivityStarter(mNotificationActivityStarter); + mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter); mNotificationsController.initialize( @@ -2909,6 +2955,12 @@ public class StatusBar extends SystemUI implements DemoMode, isSecure ? 1 : 0, unlocked ? 1 : 0); mLastLoggedStateFingerprint = stateFingerprint; + + StringBuilder uiEventValueBuilder = new StringBuilder(); + uiEventValueBuilder.append(isBouncerShowing ? "BOUNCER" : "LOCKSCREEN"); + uiEventValueBuilder.append(isShowing ? "_OPEN" : "_CLOSE"); + uiEventValueBuilder.append(isSecure ? "_SECURE" : "_INSECURE"); + sUiEventLogger.log(StatusBarUiEvent.valueOf(uiEventValueBuilder.toString())); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index fbe3e9b19248..d40b5f9728dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -35,6 +35,7 @@ import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; +import android.provider.Settings; import android.service.dreams.IDreamManager; import android.service.notification.NotificationStats; import android.service.notification.StatusBarNotification; @@ -470,6 +471,29 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit }, null, false /* afterKeyguardGone */); } + @Override + public void startHistoryIntent(boolean showHistory) { + mActivityStarter.dismissKeyguardThenExecute(() -> { + AsyncTask.execute(() -> { + Intent intent = showHistory ? new Intent( + Settings.ACTION_NOTIFICATION_HISTORY) : new Intent( + Settings.ACTION_NOTIFICATION_SETTINGS); + TaskStackBuilder tsb = TaskStackBuilder.create(mContext) + .addNextIntent(new Intent(Settings.ACTION_NOTIFICATION_SETTINGS)); + if (showHistory) { + tsb.addNextIntent(intent); + } + tsb.startActivities(); + if (shouldCollapse()) { + // Putting it back on the main thread, since we're touching views + mMainThreadHandler.post(() -> mCommandQueue.animateCollapsePanels( + CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */)); + } + }); + return true; + }, null, false /* afterKeyguardGone */); + } + private void handleFullScreenIntent(NotificationEntry entry) { if (mNotificationInterruptStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) { if (shouldSuppressFullScreenIntent(entry)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java index 6193a8e9005b..428de9e9adbb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java @@ -30,6 +30,7 @@ import android.content.IntentSender; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; +import android.util.Log; import android.view.View; import android.view.ViewParent; @@ -47,6 +48,8 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.KeyguardStateController; +import java.util.concurrent.atomic.AtomicReference; + import javax.inject.Inject; import javax.inject.Singleton; @@ -54,7 +57,8 @@ import javax.inject.Singleton; */ @Singleton public class StatusBarRemoteInputCallback implements Callback, Callbacks, - StatusBarStateController.StateListener { + StatusBarStateController.StateListener, KeyguardStateController.Callback { + private static final String TAG = StatusBarRemoteInputCallback.class.getSimpleName(); private final KeyguardStateController mKeyguardStateController; private final SysuiStatusBarStateController mStatusBarStateController; @@ -72,6 +76,7 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, private int mDisabled2; protected BroadcastReceiver mChallengeReceiver = new ChallengeReceiver(); private Handler mMainHandler = new Handler(); + private final AtomicReference<Intent> mPendingConfirmCredentialIntent = new AtomicReference(); /** */ @@ -98,6 +103,9 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, mCommandQueue.addCallback(this); mActivityIntentHelper = new ActivityIntentHelper(mContext); mGroupManager = groupManager; + // Listen to onKeyguardShowingChanged in case a managed profile needs to be unlocked + // once the primary profile's keyguard is no longer shown. + mKeyguardStateController.addCallback(this); } @Override @@ -201,12 +209,39 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, // Clear pending remote view, as we do not want to trigger pending remote input view when // it's called by other code mPendingWorkRemoteInputView = null; - // Begin old BaseStatusBar.startWorkChallengeIfNecessary. + + final Intent newIntent = createConfirmDeviceCredentialIntent( + userId, intendSender, notificationKey); + if (newIntent == null) { + Log.w(TAG, String.format("Cannot create intent to unlock user %d", userId)); + return false; + } + + mPendingConfirmCredentialIntent.set(newIntent); + + // If the Keyguard is currently showing, starting the ConfirmDeviceCredentialActivity + // would cause it to pause, not letting the user actually unlock the managed profile. + // Instead, wait until we receive a callback indicating it is no longer showing and + // then start the pending intent. + if (mKeyguardStateController.isShowing()) { + // Do nothing, since the callback will get the pending intent and start it. + Log.w(TAG, String.format("Keyguard is showing, waiting until it's not")); + } else { + startPendingConfirmDeviceCredentialIntent(); + } + + return true; + } + + private Intent createConfirmDeviceCredentialIntent( + int userId, IntentSender intendSender, String notificationKey) { final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null, userId); + if (newIntent == null) { - return false; + return null; } + final Intent callBackIntent = new Intent(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION); callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender); callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey); @@ -222,14 +257,40 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, newIntent.putExtra( Intent.EXTRA_INTENT, callBackPendingIntent.getIntentSender()); + + return newIntent; + } + + private void startPendingConfirmDeviceCredentialIntent() { + final Intent pendingIntent = mPendingConfirmCredentialIntent.getAndSet(null); + if (pendingIntent == null) { + return; + } + try { - ActivityManager.getService().startConfirmDeviceCredentialIntent(newIntent, + if (mKeyguardStateController.isShowing()) { + Log.w(TAG, "Keyguard is showing while starting confirm device credential intent."); + } + ActivityManager.getService().startConfirmDeviceCredentialIntent(pendingIntent, null /*options*/); } catch (RemoteException ex) { // ignore } - return true; - // End old BaseStatusBar.startWorkChallengeIfNecessary. + } + + @Override + public void onKeyguardShowingChanged() { + if (mKeyguardStateController.isShowing()) { + // In order to avoid jarring UX where/ the managed profile challenge is shown and + // immediately dismissed, do not attempt to start the confirm device credential + // activity if the keyguard is still showing. + if (mPendingConfirmCredentialIntent.get() != null) { + Log.w(TAG, "There's a pending unlock intent but keyguard is still showing, abort."); + } + return; + } + + startPendingConfirmDeviceCredentialIntent(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java index 899aabb2e9a7..0b6e4b2ab598 100644 --- a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java +++ b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java @@ -201,6 +201,14 @@ public class SystemWindows { attrs.flags |= FLAG_HARDWARE_ACCELERATED; viewRoot.setView(view, attrs); mViewRoots.put(view, viewRoot); + + try { + mWmService.setShellRootAccessibilityWindow(mDisplayId, windowType, + viewRoot.getWindowToken()); + } catch (RemoteException e) { + Slog.e(TAG, "Error setting accessibility window for " + mDisplayId + ":" + + windowType, e); + } } SysUiWindowManager addRoot(int windowType) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java index 9985d21e8515..dc027997578f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java @@ -19,6 +19,7 @@ package com.android.systemui.doze; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -83,7 +84,16 @@ public class DozeDockHandlerTest extends SysuiTestCase { } @Test + public void onEvent_noneWhileEnabledAod_ignoresIfAlreadyNone() { + mDockManagerFake.setDockEvent(DockManager.STATE_NONE); + + verify(mMachine, never()).requestState(eq(State.DOZE_AOD)); + } + + @Test public void onEvent_noneWhileEnabledAod_requestsAodState() { + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED); + clearInvocations(mMachine); mDockManagerFake.setDockEvent(DockManager.STATE_NONE); verify(mMachine).requestState(eq(State.DOZE_AOD)); @@ -91,6 +101,8 @@ public class DozeDockHandlerTest extends SysuiTestCase { @Test public void onEvent_noneWhileDisabledAod_requestsDozeState() { + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED); + clearInvocations(mMachine); doReturn(false).when(mConfig).alwaysOnEnabled(anyInt()); mDockManagerFake.setDockEvent(DockManager.STATE_NONE); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java index ff03fbae3f3a..317500cf5b02 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java @@ -158,6 +158,13 @@ public class DozeSensorsTest extends SysuiTestCase { verify(mTriggerSensor).setListening(eq(false)); } + @Test + public void testDestroy() { + mDozeSensors.destroy(); + + verify(mTriggerSensor).setListening(false); + } + private class TestableDozeSensors extends DozeSensors { TestableDozeSensors() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java index 9a32b1db2ff3..392adf99e511 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java @@ -44,6 +44,7 @@ import com.android.systemui.plugins.qs.QSTileView; import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.util.concurrency.DelayableExecutor; import org.junit.Before; @@ -91,6 +92,8 @@ public class QSPanelTest extends SysuiTestCase { private LocalBluetoothManager mLocalBluetoothManager; @Mock private ActivityStarter mActivityStarter; + @Mock + private NotificationEntryManager mEntryManager; @Before public void setup() throws Exception { @@ -101,7 +104,7 @@ public class QSPanelTest extends SysuiTestCase { mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); mQsPanel = new QSPanel(mContext, null, mDumpManager, mBroadcastDispatcher, mQSLogger, mForegroundExecutor, mBackgroundExecutor, - mLocalBluetoothManager, mActivityStarter); + mLocalBluetoothManager, mActivityStarter, mEntryManager); // Provides a parent with non-zero size for QSPanel mParentView = new FrameLayout(mContext); mParentView.addView(mQsPanel); diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java index ffe3cd5bd504..2c4304d51720 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java @@ -83,8 +83,9 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { eq(false))).thenThrow( RuntimeException.class); CompletableFuture<List<Notification.Action>> smartActionsFuture = - ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap, - smartActionsProvider, true, false); + ScreenshotSmartActions.getSmartActionsFuture( + "", Uri.parse("content://authority/data"), bitmap, smartActionsProvider, + true, false); assertNotNull(smartActionsFuture); List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS); assertEquals(Collections.emptyList(), smartActions); @@ -101,7 +102,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { when(smartActionsFuture.get(timeoutMs, TimeUnit.MILLISECONDS)).thenThrow( RuntimeException.class); List<Notification.Action> actions = ScreenshotSmartActions.getSmartActions( - "", "", smartActionsFuture, timeoutMs, mSmartActionsProvider); + "", smartActionsFuture, timeoutMs, mSmartActionsProvider); assertEquals(Collections.emptyList(), actions); } @@ -122,8 +123,9 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { Bitmap bitmap = mock(Bitmap.class); when(bitmap.getConfig()).thenReturn(Bitmap.Config.RGB_565); CompletableFuture<List<Notification.Action>> smartActionsFuture = - ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap, - mSmartActionsProvider, true, true); + ScreenshotSmartActions.getSmartActionsFuture( + "", Uri.parse("content://autority/data"), bitmap, mSmartActionsProvider, + true, true); verify(mSmartActionsProvider, never()).getActions(any(), any(), any(), any(), eq(false)); assertNotNull(smartActionsFuture); @@ -136,8 +138,9 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { public void testScreenshotNotificationSmartActionsProviderInvokedOnce() { Bitmap bitmap = mock(Bitmap.class); when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE); - ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap, mSmartActionsProvider, - true, true); + ScreenshotSmartActions.getSmartActionsFuture( + "", Uri.parse("content://autority/data"), bitmap, mSmartActionsProvider, true, + true); verify(mSmartActionsProvider, times(1)) .getActions(any(), any(), any(), any(), eq(true)); } @@ -152,7 +155,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider( mContext, null, mHandler); CompletableFuture<List<Notification.Action>> smartActionsFuture = - ScreenshotSmartActions.getSmartActionsFuture("", "", bitmap, + ScreenshotSmartActions.getSmartActionsFuture("", null, bitmap, actionsProvider, true, true); assertNotNull(smartActionsFuture); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java index c6d57e6df028..d124bad438c3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java @@ -20,6 +20,8 @@ import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.content.Intent.ACTION_USER_SWITCHED; import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL; +import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_MEDIA_CONTROLS; +import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT; import static junit.framework.Assert.assertFalse; @@ -42,6 +44,7 @@ import android.content.pm.UserInfo; import android.database.ContentObserver; import android.os.Handler; import android.os.Looper; +import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.testing.AndroidTestingRunner; @@ -99,6 +102,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { private UserInfo mSecondaryUser; private UserInfo mWorkUser; private TestNotificationLockscreenUserManager mLockscreenUserManager; + private NotificationEntry mCurrentUserNotif; + private NotificationEntry mSecondaryUserNotif; + private NotificationEntry mWorkProfileNotif; @Before public void setUp() { @@ -116,6 +122,21 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mDependency.injectTestDependency(Dependency.MAIN_HANDLER, Handler.createAsync(Looper.myLooper())); + Notification notifWithPrivateVisibility = new Notification(); + notifWithPrivateVisibility.visibility = Notification.VISIBILITY_PRIVATE; + mCurrentUserNotif = new NotificationEntryBuilder() + .setNotification(notifWithPrivateVisibility) + .setUser(new UserHandle(mCurrentUser.id)) + .build(); + mSecondaryUserNotif = new NotificationEntryBuilder() + .setNotification(notifWithPrivateVisibility) + .setUser(new UserHandle(mSecondaryUser.id)) + .build(); + mWorkProfileNotif = new NotificationEntryBuilder() + .setNotification(notifWithPrivateVisibility) + .setUser(new UserHandle(mWorkUser.id)) + .build(); + mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext); mLockscreenUserManager.setUpWithPresenter(mPresenter); } @@ -155,7 +176,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); - assertFalse(mLockscreenUserManager.userAllowsNotificationsInPublic(mCurrentUser.id)); + assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id)); } @Test @@ -163,7 +184,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); - assertFalse(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic()); + assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); } @Test @@ -171,7 +192,107 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); - assertTrue(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic()); + assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); + } + + @Test + public void testCurrentUserPrivateNotificationsNotRedacted() { + // GIVEN current user doesn't allow private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN current user's notification is redacted + assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + } + + @Test + public void testCurrentUserPrivateNotificationsRedacted() { + // GIVEN current user allows private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN current user's notification isn't redacted + assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + } + + @Test + public void testWorkPrivateNotificationsRedacted() { + // GIVEN work profile doesn't private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN work profile notification is redacted + assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + } + + @Test + public void testWorkPrivateNotificationsNotRedacted() { + // GIVEN work profile allows private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN work profile notification isn't redacted + assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + } + + @Test + public void testWorkPrivateNotificationsNotRedacted_otherUsersRedacted() { + // GIVEN work profile allows private notifications to show but the other users don't + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mSecondaryUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN the work profile notification doesn't need to be redacted + assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + + // THEN the current user and secondary user notifications do need to be redacted + assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); + } + + @Test + public void testWorkProfileRedacted_otherUsersNotRedacted() { + // GIVEN work profile doesn't allow private notifications to show but the other users do + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mSecondaryUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN the work profile notification needs to be redacted + assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + + // THEN the current user and secondary user notifications don't need to be redacted + assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + assertFalse(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); + } + + @Test + public void testSecondaryUserNotRedacted_currentUserRedacted() { + // GIVEN secondary profile allows private notifications to show but the current user + // doesn't allow private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mSecondaryUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN the secondary profile notification still needs to be redacted because the current + // user's setting takes precedence + assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); } @Test @@ -233,6 +354,45 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(entry)); } + @Test + public void testShowSilentNotificationsPeopleBucket_settingSaysHide() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + Settings.Secure.putInt(mContext.getContentResolver(), + NOTIFICATION_NEW_INTERRUPTION_MODEL, 1); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + + final Notification notification = mock(Notification.class); + when(notification.isForegroundService()).thenReturn(true); + NotificationEntry entry = new NotificationEntryBuilder() + .setImportance(IMPORTANCE_LOW) + .setNotification(notification) + .build(); + entry.setBucket(BUCKET_PEOPLE); + assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(entry)); + } + + @Test + public void testShowSilentNotificationsMediaBucket_settingSaysHide() { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + Settings.Secure.putInt(mContext.getContentResolver(), + NOTIFICATION_NEW_INTERRUPTION_MODEL, 1); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + + final Notification notification = mock(Notification.class); + when(notification.isForegroundService()).thenReturn(true); + NotificationEntry entry = new NotificationEntryBuilder() + .setImportance(IMPORTANCE_LOW) + .setNotification(notification) + .build(); + entry.setBucket(BUCKET_MEDIA_CONTROLS); + // always show media controls, even if they're silent + assertTrue(mLockscreenUserManager.shouldShowOnKeyguard(entry)); + } + private class TestNotificationLockscreenUserManager extends NotificationLockscreenUserManagerImpl { public TestNotificationLockscreenUserManager(Context context) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index d41b6cfb32c0..92a2c8738344 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -43,6 +43,7 @@ import com.android.systemui.bubbles.BubbleController; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.statusbar.notification.DynamicChildBindController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -329,6 +330,10 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { } @Override + public void setNotificationActivityStarter( + NotificationActivityStarter notificationActivityStarter) {} + + @Override public void addContainerView(View v) { mLayout.addView(v); mRows.add(v); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java index 29040147d1ca..d0dfb17111c6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java @@ -80,7 +80,7 @@ public class DynamicChildBindControllerTest extends SysuiTestCase { when(mBindStage.getStageParams(lastChild)).thenReturn(bindParams); // WHEN the controller gets the list - mDynamicChildBindController.updateChildContentViews(mGroupNotifs); + mDynamicChildBindController.updateContentViews(mGroupNotifs); // THEN we free content views verify(bindParams).markContentViewsFreeable(FLAG_CONTENT_VIEW_CONTRACTED); @@ -101,7 +101,7 @@ public class DynamicChildBindControllerTest extends SysuiTestCase { when(mBindStage.getStageParams(lastChild)).thenReturn(bindParams); // WHEN the controller gets the list - mDynamicChildBindController.updateChildContentViews(mGroupNotifs); + mDynamicChildBindController.updateContentViews(mGroupNotifs); // THEN we bind content views verify(bindParams).requireContentViews(FLAG_CONTENT_VIEW_CONTRACTED); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt index a2599ecb50da..b4cabfd1855d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt @@ -32,6 +32,7 @@ import com.android.systemui.statusbar.notification.NotificationFilter import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow @@ -228,6 +229,56 @@ class NotificationRankingManagerTest : SysuiTestCase() { whenever(personNotificationIdentifier.getPeopleNotificationType(b.sbn, b.ranking)) .thenReturn(TYPE_IMPORTANT_PERSON) + whenever(personNotificationIdentifier.compareTo(TYPE_PERSON, TYPE_IMPORTANT_PERSON)) + .thenReturn(TYPE_IMPORTANT_PERSON.compareTo(TYPE_PERSON)) + whenever(personNotificationIdentifier.compareTo(TYPE_IMPORTANT_PERSON, TYPE_PERSON)) + .thenReturn(TYPE_PERSON.compareTo(TYPE_IMPORTANT_PERSON)) + + assertEquals( + listOf(b, a), + rankingManager.updateRanking(null, listOf(a, b), "test")) + } + + @Test + fun testSort_fullPeople() { + whenever(sectionsManager.isFilteringEnabled()).thenReturn(true) + val aN = Notification.Builder(mContext, "test") + .setStyle(Notification.MessagingStyle("")) + .build() + val a = NotificationEntryBuilder() + .setImportance(IMPORTANCE_HIGH) + .setPkg("pkg") + .setOpPkg("pkg") + .setTag("tag") + .setNotification(aN) + .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT)) + .setUser(mContext.user) + .setOverrideGroupKey("") + .build() + whenever(personNotificationIdentifier.getPeopleNotificationType(a.sbn, a.ranking)) + .thenReturn(TYPE_PERSON) + + val bN = Notification.Builder(mContext, "test") + .setStyle(Notification.MessagingStyle("")) + .build() + val b = NotificationEntryBuilder() + .setImportance(IMPORTANCE_HIGH) + .setPkg("pkg2") + .setOpPkg("pkg2") + .setTag("tag") + .setNotification(bN) + .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT)) + .setUser(mContext.user) + .setOverrideGroupKey("") + .build() + whenever(personNotificationIdentifier.getPeopleNotificationType(b.sbn, b.ranking)) + .thenReturn(TYPE_FULL_PERSON) + + whenever(personNotificationIdentifier.compareTo(TYPE_PERSON, TYPE_FULL_PERSON)) + .thenReturn(TYPE_FULL_PERSON.compareTo(TYPE_PERSON)) + whenever(personNotificationIdentifier.compareTo(TYPE_FULL_PERSON, TYPE_PERSON)) + .thenReturn(TYPE_PERSON.compareTo(TYPE_FULL_PERSON)) + assertEquals( listOf(b, a), rankingManager.updateRanking(null, listOf(a, b), "test")) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java index 4f481081855f..f54252effdd3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java @@ -176,6 +176,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { .setKey(mEntry.getKey()) .setImportance(IMPORTANCE_MIN) .build()); + when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false); // THEN filter out the entry assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0)); @@ -197,7 +198,8 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { .setImportance(IMPORTANCE_MIN) .build()); - // WHEN its parent has a summary that exceeds threshold to show on lockscreen + // WHEN its parent does exceed threshold tot show on the lockscreen + when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(true); parent.setSummary(new NotificationEntryBuilder() .setImportance(IMPORTANCE_HIGH) .build()); @@ -205,7 +207,8 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { // THEN don't filter out the entry assertFalse(mKeyguardFilter.shouldFilterOut(entryWithParent, 0)); - // WHEN its parent has a summary that doesn't exceed threshold to show on lockscreen + // WHEN its parent doesn't exceed threshold to show on lockscreen + when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(false); parent.setSummary(new NotificationEntryBuilder() .setImportance(IMPORTANCE_MIN) .build()); @@ -248,5 +251,8 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { .thenReturn(true); // notification doesn't have a summary + + // notification is high priority, so it shouldn't be filtered + when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(true); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java index 3847028a25df..dbf40e467c95 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java @@ -386,7 +386,10 @@ public class NotificationConversationInfoTest extends SysuiTestCase { applicationInfo); when(mMockPackageManager.getApplicationLabel(any())).thenReturn("Other"); - NotificationEntry entry = new NotificationEntryBuilder().setSbn(mSbn).build(); + NotificationEntry entry = new NotificationEntryBuilder() + .setSbn(mSbn) + .setShortcutInfo(mShortcutInfo) + .build(); mNotificationInfo.bindNotification( mShortcutManager, mMockPackageManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java new file mode 100644 index 000000000000..c390e3933d7a --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.notification.row; + +import static android.app.Notification.EXTRA_IS_GROUP_CONVERSATION; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.app.INotificationManager; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationChannelGroup; +import android.app.Person; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; +import android.os.UserHandle; +import android.service.notification.StatusBarNotification; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.internal.logging.MetricsLogger; +import com.android.systemui.Dependency; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CountDownLatch; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class PartialConversationInfoTest extends SysuiTestCase { + private static final String TEST_PACKAGE_NAME = "test_package"; + private static final String TEST_SYSTEM_PACKAGE_NAME = PRINT_SPOOLER_PACKAGE_NAME; + private static final int TEST_UID = 1; + private static final String TEST_CHANNEL = "test_channel"; + private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME"; + + private TestableLooper mTestableLooper; + private PartialConversationInfo mInfo; + private NotificationChannel mNotificationChannel; + private NotificationChannel mDefaultNotificationChannel; + private Set<NotificationChannel> mNotificationChannelSet = new HashSet<>(); + private Set<NotificationChannel> mDefaultNotificationChannelSet = new HashSet<>(); + private StatusBarNotification mSbn; + private NotificationEntry mEntry; + + @Rule + public MockitoRule mockito = MockitoJUnit.rule(); + @Mock + private MetricsLogger mMetricsLogger; + @Mock + private INotificationManager mMockINotificationManager; + @Mock + private PackageManager mMockPackageManager; + + @Mock + private Icon mIcon; + @Mock + private Drawable mDrawable; + + @Before + public void setUp() throws Exception { + mTestableLooper = TestableLooper.get(this); + + mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); + mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); + // Inflate the layout + final LayoutInflater layoutInflater = LayoutInflater.from(mContext); + mInfo = (PartialConversationInfo) layoutInflater.inflate(R.layout.partial_conversation_info, + null); + mInfo.setGutsParent(mock(NotificationGuts.class)); + // Our view is never attached to a window so the View#post methods in NotificationInfo never + // get called. Setting this will skip the post and do the action immediately. + mInfo.mSkipPost = true; + + // PackageManager must return a packageInfo and applicationInfo. + final PackageInfo packageInfo = new PackageInfo(); + packageInfo.packageName = TEST_PACKAGE_NAME; + when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt())) + .thenReturn(packageInfo); + final ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.uid = TEST_UID; // non-zero + when(mMockPackageManager.getApplicationInfo(eq(TEST_PACKAGE_NAME), anyInt())).thenReturn( + applicationInfo); + final PackageInfo systemPackageInfo = new PackageInfo(); + systemPackageInfo.packageName = TEST_SYSTEM_PACKAGE_NAME; + when(mMockPackageManager.getPackageInfo(eq(TEST_SYSTEM_PACKAGE_NAME), anyInt())) + .thenReturn(systemPackageInfo); + when(mMockPackageManager.getPackageInfo(eq("android"), anyInt())) + .thenReturn(packageInfo); + + // Package has one channel by default. + when(mMockINotificationManager.getNumNotificationChannelsForPackage( + eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(1); + + when(mIcon.loadDrawable(any())).thenReturn(mDrawable); + + // Some test channels. + mNotificationChannel = new NotificationChannel( + TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW); + mNotificationChannelSet.add(mNotificationChannel); + mDefaultNotificationChannel = new NotificationChannel( + NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME, + IMPORTANCE_LOW); + mDefaultNotificationChannelSet.add(mDefaultNotificationChannel); + mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0, + new Notification(), UserHandle.CURRENT, null, 0); + mEntry = new NotificationEntryBuilder().setSbn(mSbn).build(); + } + + @Test + public void testBindNotification_SetsTextApplicationName() throws Exception { + when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name"); + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final TextView textView = mInfo.findViewById(R.id.pkg_name); + assertTrue(textView.getText().toString().contains("App Name")); + assertEquals(VISIBLE, mInfo.findViewById(R.id.header).getVisibility()); + } + + @Test + public void testBindNotification_groupSetsPackageIcon() { + mEntry.getSbn().getNotification().extras.putBoolean(EXTRA_IS_GROUP_CONVERSATION, true); + final Drawable iconDrawable = mock(Drawable.class); + when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class))) + .thenReturn(iconDrawable); + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final ImageView iconView = mInfo.findViewById(R.id.conversation_icon); + assertEquals(iconDrawable, iconView.getDrawable()); + } + + @Test + public void testBindNotification_notGroupSetsMessageIcon() { + Notification n = new Notification.Builder(mContext, TEST_CHANNEL_NAME) + .setStyle(new Notification.MessagingStyle( + new Person.Builder().setName("me").build()) + .addMessage(new Notification.MessagingStyle.Message("hello", 0, + new Person.Builder().setName("friend").setIcon(mIcon).build()))) + .build(); + mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0, + n, UserHandle.CURRENT, null, 0); + mEntry.setSbn(mSbn); + mEntry.getSbn().getNotification().extras.putBoolean(EXTRA_IS_GROUP_CONVERSATION, false); + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final ImageView iconView = mInfo.findViewById(R.id.conversation_icon); + assertEquals(mDrawable.hashCode() + "", mDrawable, iconView.getDrawable()); + } + + @Test + public void testBindNotification_noDelegate() { + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final TextView nameView = mInfo.findViewById(R.id.delegate_name); + assertEquals(GONE, nameView.getVisibility()); + final TextView dividerView = mInfo.findViewById(R.id.group_divider); + assertEquals(GONE, dividerView.getVisibility()); + } + + @Test + public void testBindNotification_delegate() throws Exception { + mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, "other", 0, null, TEST_UID, 0, + new Notification(), UserHandle.CURRENT, null, 0); + final ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.uid = 7; // non-zero + when(mMockPackageManager.getApplicationInfo(eq("other"), anyInt())).thenReturn( + applicationInfo); + when(mMockPackageManager.getApplicationLabel(any())).thenReturn("Other"); + + NotificationEntry entry = new NotificationEntryBuilder().setSbn(mSbn).build(); + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + entry, + null, + true, + false); + final TextView nameView = mInfo.findViewById(R.id.delegate_name); + assertEquals(VISIBLE, nameView.getVisibility()); + assertTrue(nameView.getText().toString().contains("Proxied")); + } + + @Test + public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception { + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final TextView groupNameView = mInfo.findViewById(R.id.group_name); + assertEquals(GONE, groupNameView.getVisibility()); + final TextView dividerView = mInfo.findViewById(R.id.group_divider); + assertEquals(GONE, dividerView.getVisibility()); + } + + @Test + public void testBindNotification_SetsGroupNameIfNonNull() throws Exception { + mNotificationChannel.setGroup("test_group_id"); + final NotificationChannelGroup notificationChannelGroup = + new NotificationChannelGroup("test_group_id", "Test Group Name"); + when(mMockINotificationManager.getNotificationChannelGroupForPackage( + eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID))) + .thenReturn(notificationChannelGroup); + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final TextView groupNameView = mInfo.findViewById(R.id.group_name); + assertEquals(View.VISIBLE, groupNameView.getVisibility()); + assertEquals("Test Group Name", groupNameView.getText()); + final TextView dividerView = mInfo.findViewById(R.id.group_divider); + assertEquals(View.VISIBLE, dividerView.getVisibility()); + } + + @Test + public void testBindNotification_SetsTextChannelName() { + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final TextView textView = mInfo.findViewById(R.id.parent_channel_name); + assertEquals(TEST_CHANNEL_NAME, textView.getText()); + } + + @Test + public void testBindNotification_SetsOnClickListenerForSettings() { + final CountDownLatch latch = new CountDownLatch(1); + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + (View v, NotificationChannel c, int appUid) -> { + assertEquals(mNotificationChannel, c); + latch.countDown(); + }, + true, + false); + + final View settingsButton = mInfo.findViewById(R.id.info); + settingsButton.performClick(); + // Verify that listener was triggered. + assertEquals(0, latch.getCount()); + } + + @Test + public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() { + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + false); + final View settingsButton = mInfo.findViewById(R.id.info); + assertTrue(settingsButton.getVisibility() != View.VISIBLE); + } + + @Test + public void testBindNotification_SettingsButtonInvisibleWhenDeviceUnprovisioned() { + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + (View v, NotificationChannel c, int appUid) -> { + assertEquals(mNotificationChannel, c); + }, + false, + false); + final View settingsButton = mInfo.findViewById(R.id.info); + assertTrue(settingsButton.getVisibility() != View.VISIBLE); + } + + @Test + public void testBindNotification_whenAppUnblockable() { + mInfo.bindNotification( + mMockPackageManager, + mMockINotificationManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mNotificationChannelSet, + mEntry, + null, + true, + true); + + assertEquals(GONE, + mInfo.findViewById(R.id.turn_off_notifications).getVisibility()); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java index 703789151895..b9055ec0bb7b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java @@ -146,7 +146,7 @@ public class NotificationChildrenContainerTest extends SysuiTestCase { @Test public void testRecreateNotificationHeader_hasHeader() { - mChildrenContainer.recreateNotificationHeader(null); + mChildrenContainer.recreateNotificationHeader(null, false); Assert.assertNotNull("Children container must have a header after recreation", mChildrenContainer.getCurrentHeaderView()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java index 9aa0fdd2a6f7..a77f8c649f30 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java @@ -62,6 +62,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dependency; import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.SysuiTestableContext; +import com.android.systemui.accessibility.SystemActions; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.model.SysUiState; @@ -102,6 +103,8 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest { private Divider mDivider; @Mock private Recents mRecents; + @Mock + private SystemActions mSystemActions; private AccessibilityManagerWrapper mAccessibilityWrapper = new AccessibilityManagerWrapper(mContext) { @@ -257,6 +260,7 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest { () -> mock(StatusBar.class), mock(ShadeController.class), mock(NotificationRemoteInputManager.class), + mock(SystemActions.class), mHandler); } diff --git a/packages/Tethering/jarjar-rules.txt b/packages/Tethering/jarjar-rules.txt index c6efa41e580a..e90a2ccaa2a3 100644 --- a/packages/Tethering/jarjar-rules.txt +++ b/packages/Tethering/jarjar-rules.txt @@ -8,7 +8,6 @@ rule com.android.internal.util.BitUtils* com.android.networkstack.tethering.util rule com.android.internal.util.IndentingPrintWriter.java* com.android.networkstack.tethering.util.IndentingPrintWriter.java@1 rule com.android.internal.util.IState.java* com.android.networkstack.tethering.util.IState.java@1 rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering.util.MessageUtils@1 -rule com.android.internal.util.Preconditions* com.android.networkstack.tethering.util.Preconditions@1 rule com.android.internal.util.State* com.android.networkstack.tethering.util.State@1 rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1 rule com.android.internal.util.TrafficStatsConstants* com.android.networkstack.tethering.util.TrafficStatsConstants@1 diff --git a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml index 2a7330098faf..12d6c2cfbaeb 100644 --- a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml +++ b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml @@ -16,13 +16,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for no_upstream_notification_title (5030042590486713460) --> - <skip /> - <!-- no translation found for no_upstream_notification_message (3843613362272973447) --> - <skip /> - <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) --> - <skip /> - <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) --> - <skip /> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिङ निष्क्रिय पार्नुहोस्"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हटस्पट वा टेदरिङ सक्रिय छ"</string> <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string> </resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml index ea04821e33bd..f4b15aab19b7 100644 --- a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml +++ b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml @@ -16,13 +16,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for no_upstream_notification_title (5030042590486713460) --> - <skip /> - <!-- no translation found for no_upstream_notification_message (3843613362272973447) --> - <skip /> - <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) --> - <skip /> - <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) --> - <skip /> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"சாதனங்களால் இணைய முடியவில்லை"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"இணைப்பு முறையை ஆஃப் செய்"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string> <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string> </resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml index 617c50dd0ce8..0a0aa217c381 100644 --- a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml +++ b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml @@ -16,13 +16,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for no_upstream_notification_title (611650570559011140) --> - <skip /> - <!-- no translation found for no_upstream_notification_message (6508394877641864863) --> - <skip /> - <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) --> - <skip /> - <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) --> - <skip /> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिङ निष्क्रिय पार्नुहोस्"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हटस्पट वा टेदरिङ सक्रिय छ"</string> <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string> </resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml index 0e437593ee87..2ea2467e5879 100644 --- a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml +++ b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml @@ -16,13 +16,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for no_upstream_notification_title (611650570559011140) --> - <skip /> - <!-- no translation found for no_upstream_notification_message (6508394877641864863) --> - <skip /> - <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) --> - <skip /> - <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) --> - <skip /> + <string name="no_upstream_notification_title" msgid="611650570559011140">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"சாதனங்களால் இணைய முடியவில்லை"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"இணைப்பு முறையை ஆஃப் செய்"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string> <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string> </resources> diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java index 82a26beadacf..4f8ad8a221ef 100644 --- a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java +++ b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java @@ -169,7 +169,7 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel { * <p>If not set, the default value is null. */ public DhcpServingParamsParcelExt setSingleClientAddr(@Nullable Inet4Address clientAddr) { - this.clientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr); + this.singleClientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr); return this; } diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java index c007c174fe4f..1817f35f1dcd 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java @@ -23,6 +23,7 @@ import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStats.UID_TETHERING; +import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED; import android.annotation.NonNull; @@ -76,6 +77,7 @@ public class OffloadController { private static final boolean DBG = false; private static final String ANYIP = "0.0.0.0"; private static final ForwardedStats EMPTY_STATS = new ForwardedStats(); + private static final int DEFAULT_PERFORM_POLL_INTERVAL_MS = 5000; @VisibleForTesting enum StatsType { @@ -115,11 +117,33 @@ public class OffloadController { // includes upstream interfaces that have a quota set. private HashMap<String, Long> mInterfaceQuotas = new HashMap<>(); + // Tracking remaining alert quota. Unlike limit quota is subject to interface, the alert + // quota is interface independent and global for tether offload. Note that this is only + // accessed on the handler thread and in the constructor. + private long mRemainingAlertQuota = QUOTA_UNLIMITED; + // Runnable that used to schedule the next stats poll. + private final Runnable mScheduledPollingTask = () -> { + updateStatsForCurrentUpstream(); + maybeSchedulePollingStats(); + }; + private int mNatUpdateCallbacksReceived; private int mNatUpdateNetlinkErrors; + @NonNull + private final Dependencies mDeps; + + // TODO: Put more parameters in constructor into dependency object. + static class Dependencies { + int getPerformPollInterval() { + // TODO: Consider make this configurable. + return DEFAULT_PERFORM_POLL_INTERVAL_MS; + } + } + public OffloadController(Handler h, OffloadHardwareInterface hwi, - ContentResolver contentResolver, NetworkStatsManager nsm, SharedLog log) { + ContentResolver contentResolver, NetworkStatsManager nsm, SharedLog log, + @NonNull Dependencies deps) { mHandler = h; mHwInterface = hwi; mContentResolver = contentResolver; @@ -135,6 +159,7 @@ public class OffloadController { provider = null; } mStatsProvider = provider; + mDeps = deps; } /** Start hardware offload. */ @@ -240,6 +265,7 @@ public class OffloadController { mLog.log("tethering offload started"); mNatUpdateCallbacksReceived = 0; mNatUpdateNetlinkErrors = 0; + maybeSchedulePollingStats(); } return isStarted; } @@ -255,6 +281,9 @@ public class OffloadController { mHwInterface.stopOffloadControl(); mControlInitialized = false; mConfigInitialized = false; + if (mHandler.hasCallbacks(mScheduledPollingTask)) { + mHandler.removeCallbacks(mScheduledPollingTask); + } if (wasStarted) mLog.log("tethering offload stopped"); } @@ -345,6 +374,11 @@ public class OffloadController { @Override public void onSetAlert(long quotaBytes) { // TODO: Ask offload HAL to notify alert without stopping traffic. + // Post it to handler thread since it access remaining quota bytes. + mHandler.post(() -> { + updateAlertQuota(quotaBytes); + maybeSchedulePollingStats(); + }); } } @@ -366,15 +400,66 @@ public class OffloadController { // the stats for each interface, and does not observe partial writes where rxBytes is // updated and txBytes is not. ForwardedStats diff = mHwInterface.getForwardedStats(iface); + final long usedAlertQuota = diff.rxBytes + diff.txBytes; ForwardedStats base = mForwardedStats.get(iface); if (base != null) { diff.add(base); } + + // Update remaining alert quota if it is still positive. + if (mRemainingAlertQuota > 0 && usedAlertQuota > 0) { + // Trim to zero if overshoot. + final long newQuota = Math.max(mRemainingAlertQuota - usedAlertQuota, 0); + updateAlertQuota(newQuota); + } + mForwardedStats.put(iface, diff); // diff is a new object, just created by getForwardedStats(). Therefore, anyone reading from // mForwardedStats (i.e., any caller of getTetherStats) will see the new stats immediately. } + /** + * Update remaining alert quota, fire the {@link NetworkStatsProvider#notifyAlertReached()} + * callback when it reaches zero. This can be invoked either from service setting the alert, or + * {@code maybeUpdateStats} when updating stats. Note that this can be only called on + * handler thread. + * + * @param newQuota non-negative value to indicate the new quota, or + * {@link NetworkStatsProvider#QUOTA_UNLIMITED} to indicate there is no + * quota. + */ + private void updateAlertQuota(long newQuota) { + if (newQuota < QUOTA_UNLIMITED) { + throw new IllegalArgumentException("invalid quota value " + newQuota); + } + if (mRemainingAlertQuota == newQuota) return; + + mRemainingAlertQuota = newQuota; + if (mRemainingAlertQuota == 0) { + mLog.i("notifyAlertReached"); + if (mStatsProvider != null) mStatsProvider.notifyAlertReached(); + } + } + + /** + * Schedule polling if needed, this will be stopped if offload has been + * stopped or remaining quota reaches zero or upstream is empty. + * Note that this can be only called on handler thread. + */ + private void maybeSchedulePollingStats() { + if (!isPollingStatsNeeded()) return; + + if (mHandler.hasCallbacks(mScheduledPollingTask)) { + mHandler.removeCallbacks(mScheduledPollingTask); + } + mHandler.postDelayed(mScheduledPollingTask, mDeps.getPerformPollInterval()); + } + + private boolean isPollingStatsNeeded() { + return started() && mRemainingAlertQuota > 0 + && !TextUtils.isEmpty(currentUpstreamInterface()); + } + private boolean maybeUpdateDataLimit(String iface) { // setDataLimit may only be called while offload is occurring on this upstream. if (!started() || !TextUtils.equals(iface, currentUpstreamInterface())) { @@ -414,6 +499,8 @@ public class OffloadController { final String iface = currentUpstreamInterface(); if (!TextUtils.isEmpty(iface)) mForwardedStats.putIfAbsent(iface, EMPTY_STATS); + maybeSchedulePollingStats(); + // TODO: examine return code and decide what to do if programming // upstream parameters fails (probably just wait for a subsequent // onOffloadEvent() callback to tell us offload is available again and diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java index 55344fc75d65..293f8eae32d5 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.net.SocketAddress; import java.net.SocketException; import java.util.ArrayList; +import java.util.NoSuchElementException; /** @@ -143,7 +144,7 @@ public class OffloadHardwareInterface { IOffloadConfig offloadConfig; try { offloadConfig = IOffloadConfig.getService(true /*retry*/); - } catch (RemoteException e) { + } catch (RemoteException | NoSuchElementException e) { mLog.e("getIOffloadConfig error " + e); return false; } @@ -239,8 +240,8 @@ public class OffloadHardwareInterface { if (mOffloadControl == null) { try { - mOffloadControl = IOffloadControl.getService(); - } catch (RemoteException e) { + mOffloadControl = IOffloadControl.getService(true /*retry*/); + } catch (RemoteException | NoSuchElementException e) { mLog.e("tethering offload control not supported: " + e); return false; } @@ -307,7 +308,6 @@ public class OffloadHardwareInterface { return stats; } - mLog.log(logmsg + YIELDS + stats); return stats; } diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 4e16c49caa0e..0a95a5e0073b 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -273,7 +273,7 @@ public class Tethering { mHandler = mTetherMasterSM.getHandler(); mOffloadController = new OffloadController(mHandler, mDeps.getOffloadHardwareInterface(mHandler, mLog), mContext.getContentResolver(), - statsManager, mLog); + statsManager, mLog, new OffloadController.Dependencies()); mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK); mForwardedDownstreams = new LinkedHashSet<>(); diff --git a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java index 25ddce4404e4..320427c393ac 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java @@ -43,7 +43,6 @@ import android.util.Log; import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.Preconditions; import com.android.internal.util.StateMachine; import java.util.HashMap; @@ -591,7 +590,9 @@ public class UpstreamNetworkMonitor { // Map from type to transports. final int notFound = -1; final int transport = sLegacyTypeToTransport.get(type, notFound); - Preconditions.checkArgument(transport != notFound, "unknown legacy type: " + type); + if (transport == notFound) { + throw new IllegalArgumentException("unknown legacy type: " + type); + } builder.addTransportType(transport); if (type == TYPE_MOBILE_DUN) { diff --git a/packages/Tethering/tests/unit/jarjar-rules.txt b/packages/Tethering/tests/unit/jarjar-rules.txt index 921fbed373b0..1ea56cdf1a3d 100644 --- a/packages/Tethering/tests/unit/jarjar-rules.txt +++ b/packages/Tethering/tests/unit/jarjar-rules.txt @@ -4,7 +4,6 @@ rule com.android.internal.util.BitUtils* com.android.networkstack.tethering.util rule com.android.internal.util.IndentingPrintWriter.java* com.android.networkstack.tethering.util.IndentingPrintWriter.java@1 rule com.android.internal.util.IState.java* com.android.networkstack.tethering.util.IState.java@1 rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering.util.MessageUtils@1 -rule com.android.internal.util.Preconditions* com.android.networkstack.tethering.util.Preconditions@1 rule com.android.internal.util.State* com.android.networkstack.tethering.util.State@1 rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1 rule com.android.internal.util.TrafficStatsConstants* com.android.networkstack.tethering.util.TrafficStatsConstants@1 diff --git a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java b/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java index f8eb1476bad0..a8857b2e5cb0 100644 --- a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java +++ b/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java @@ -110,7 +110,7 @@ public class DhcpServingParamsParcelExtTest { @Test public void testSetClientAddr() { mParcel.setSingleClientAddr(TEST_CLIENT_ADDRESS); - assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.clientAddr); + assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.singleClientAddr); } private static Inet4Address inet4Addr(String addr) { diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java index 65797200fa92..088a663190b8 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java @@ -116,6 +116,12 @@ public class OffloadControllerTest { private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor = ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class); private MockContentResolver mContentResolver; + private OffloadController.Dependencies mDeps = new OffloadController.Dependencies() { + @Override + int getPerformPollInterval() { + return 0; + } + }; @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -150,7 +156,7 @@ public class OffloadControllerTest { private OffloadController makeOffloadController() throws Exception { OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()), - mHardware, mContentResolver, mStatsManager, new SharedLog("test")); + mHardware, mContentResolver, mStatsManager, new SharedLog("test"), mDeps); final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider> tetherStatsProviderCaptor = ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class); diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index 0c86eeb6cd4d..0363f5f9989f 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -1689,7 +1689,7 @@ public class TetheringTest { final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue(); assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress()); assertEquals(24, params.serverAddrPrefixLength); - assertEquals(clientAddrParceled, params.clientAddr); + assertEquals(clientAddrParceled, params.singleClientAddr); } @Test diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk index dcdb80b497d0..50e1030fda30 100644 --- a/packages/overlays/Android.mk +++ b/packages/overlays/Android.mk @@ -45,9 +45,12 @@ LOCAL_REQUIRED_MODULES := \ IconPackRoundedSettingsOverlay \ IconPackRoundedSystemUIOverlay \ IconPackRoundedThemePickerOverlay \ + IconShapePebbleOverlay \ IconShapeRoundedRectOverlay \ IconShapeSquircleOverlay \ + IconShapeTaperedRectOverlay \ IconShapeTeardropOverlay \ + IconShapeVesselOverlay \ NavigationBarMode3ButtonOverlay \ NavigationBarModeGesturalOverlay \ NavigationBarModeGesturalOverlayNarrowBack \ diff --git a/packages/overlays/IconShapeHexagonOverlay/Android.mk b/packages/overlays/IconShapeTaperedRectOverlay/Android.mk index 16ef3995dedd..6f1bf2370a15 100644 --- a/packages/overlays/IconShapeHexagonOverlay/Android.mk +++ b/packages/overlays/IconShapeTaperedRectOverlay/Android.mk @@ -17,13 +17,13 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_RRO_THEME := IconShapeHexagon +LOCAL_RRO_THEME := IconShapeTaperedRect LOCAL_PRODUCT_MODULE := true LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res -LOCAL_PACKAGE_NAME := IconShapeHexagonOverlay +LOCAL_PACKAGE_NAME := IconShapeTaperedRectOverlay LOCAL_SDK_VERSION := current include $(BUILD_RRO_PACKAGE) diff --git a/packages/overlays/IconShapeHexagonOverlay/AndroidManifest.xml b/packages/overlays/IconShapeTaperedRectOverlay/AndroidManifest.xml index bf408fd62569..61ed222327ef 100644 --- a/packages/overlays/IconShapeHexagonOverlay/AndroidManifest.xml +++ b/packages/overlays/IconShapeTaperedRectOverlay/AndroidManifest.xml @@ -15,7 +15,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.theme.icon.hexagon" + package="com.android.theme.icon.taperedrect" android:versionCode="1" android:versionName="1.0"> <overlay @@ -23,5 +23,5 @@ android:category="android.theme.customization.adaptive_icon_shape" android:priority="1"/> - <application android:label="@string/icon_shape_hexagon_overlay" android:hasCode="false"/> + <application android:label="@string/icon_shape_tapered_rect_overlay" android:hasCode="false"/> </manifest> diff --git a/packages/overlays/IconShapeHexagonOverlay/res/values/config.xml b/packages/overlays/IconShapeTaperedRectOverlay/res/values/config.xml index f7cb5951b4f1..8e80c9df1da3 100644 --- a/packages/overlays/IconShapeHexagonOverlay/res/values/config.xml +++ b/packages/overlays/IconShapeTaperedRectOverlay/res/values/config.xml @@ -16,12 +16,14 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. --> - <string name="config_icon_mask" translatable="false">"M12,0 88,0 100,50 88,100 12,100 0,50 12,0 Z"</string> + <string name="config_icon_mask" translatable="false">"M20,0 80,0 100,20 100,80 80,100 20,100 0,80 0,20 20,0 Z"</string> <!-- Flag indicating whether round icons should be parsed from the application manifest. --> <bool name="config_useRoundIcon">false</bool> <!-- Corner radius of system dialogs --> <dimen name="config_dialogCornerRadius">0dp</dimen> <!-- Corner radius for bottom sheet system dialogs --> <dimen name="config_bottomDialogCornerRadius">0dp</dimen> + <!-- Tile stroke width --> + <dimen name="config_qsTileStrokeWidthInactive">10dp</dimen> </resources> diff --git a/packages/overlays/IconShapeHexagonOverlay/res/values/strings.xml b/packages/overlays/IconShapeTaperedRectOverlay/res/values/strings.xml index e00dc9d938ec..3f36598a89bc 100644 --- a/packages/overlays/IconShapeHexagonOverlay/res/values/strings.xml +++ b/packages/overlays/IconShapeTaperedRectOverlay/res/values/strings.xml @@ -14,7 +14,7 @@ ~ limitations under the License. --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Hexagon icon overlay --> - <string name="icon_shape_hexagon_overlay" translatable="false">Hexagon</string> + <!-- Tapered rect icon overlay --> + <string name="icon_shape_tapered_rect_overlay" translatable="false">Tapered Rect</string> </resources> diff --git a/packages/overlays/IconShapeFlowerOverlay/Android.mk b/packages/overlays/IconShapeVesselOverlay/Android.mk index d410bb72b723..0816e6f7800d 100644 --- a/packages/overlays/IconShapeFlowerOverlay/Android.mk +++ b/packages/overlays/IconShapeVesselOverlay/Android.mk @@ -17,13 +17,13 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_RRO_THEME := IconShapeFlower +LOCAL_RRO_THEME := IconShapeVessel LOCAL_PRODUCT_MODULE := true LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res -LOCAL_PACKAGE_NAME := IconShapeFlowerOverlay +LOCAL_PACKAGE_NAME := IconShapeVesselOverlay LOCAL_SDK_VERSION := current include $(BUILD_RRO_PACKAGE) diff --git a/packages/overlays/IconShapeFlowerOverlay/AndroidManifest.xml b/packages/overlays/IconShapeVesselOverlay/AndroidManifest.xml index 9d20c6b6f82c..025ac6951f0b 100644 --- a/packages/overlays/IconShapeFlowerOverlay/AndroidManifest.xml +++ b/packages/overlays/IconShapeVesselOverlay/AndroidManifest.xml @@ -14,7 +14,7 @@ ~ limitations under the License. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.theme.icon.flower" + package="com.android.theme.icon.vessel" android:versionCode="1" android:versionName="1.0"> <overlay @@ -22,5 +22,5 @@ android:category="android.theme.customization.adaptive_icon_shape" android:priority="1"/> - <application android:label="@string/icon_shape_flower_overlay" android:hasCode="false"/> + <application android:label="@string/icon_shape_vessel_overlay" android:hasCode="false"/> </manifest> diff --git a/packages/overlays/IconShapeFlowerOverlay/res/values/config.xml b/packages/overlays/IconShapeVesselOverlay/res/values/config.xml index 73f4f2175a4b..86d31f6450bc 100644 --- a/packages/overlays/IconShapeFlowerOverlay/res/values/config.xml +++ b/packages/overlays/IconShapeVesselOverlay/res/values/config.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. --> - <string name="config_icon_mask" translatable="false">"M50,0 C60.6,0 69.9,5.3 75.6,13.5 78.5,17.8 82.3,21.5 86.6,24.5 94.7,30.1 100,39.4 100,50 100,60.6 94.7,69.9 86.5,75.6 82.2,78.5 78.5,82.3 75.5,86.6 69.9,94.7 60.6,100 50,100 39.4,100 30.1,94.7 24.4,86.5 21.5,82.2 17.7,78.5 13.4,75.5 5.3,69.9 0,60.6 0,50 0,39.4 5.3,30.1 13.5,24.4 17.8,21.5 21.5,17.7 24.5,13.4 30.1,5.3 39.4,0 50,0 Z"</string> + <string name="config_icon_mask" translatable="false">"M12.97,0 C8.41,0 4.14,2.55 2.21,6.68 -1.03,13.61 -0.71,21.78 3.16,28.46 4.89,31.46 4.89,35.2 3.16,38.2 -1.05,45.48 -1.05,54.52 3.16,61.8 4.89,64.8 4.89,68.54 3.16,71.54 -0.71,78.22 -1.03,86.39 2.21,93.32 4.14,97.45 8.41,100 12.97,100 21.38,100 78.62,100 87.03,100 91.59,100 95.85,97.45 97.79,93.32 101.02,86.39 100.71,78.22 96.84,71.54 95.1,68.54 95.1,64.8 96.84,61.8 101.05,54.52 101.05,45.48 96.84,38.2 95.1,35.2 95.1,31.46 96.84,28.46 100.71,21.78 101.02,13.61 97.79,6.68 95.85,2.55 91.59,0 87.03,0 78.62,0 21.38,0 12.97,0 Z"</string> <!-- Flag indicating whether round icons should be parsed from the application manifest. --> <bool name="config_useRoundIcon">false</bool> <!-- Corner radius of system dialogs --> diff --git a/packages/overlays/IconShapeFlowerOverlay/res/values/strings.xml b/packages/overlays/IconShapeVesselOverlay/res/values/strings.xml index 47c1479e5a40..a50e7e9a9ab2 100644 --- a/packages/overlays/IconShapeFlowerOverlay/res/values/strings.xml +++ b/packages/overlays/IconShapeVesselOverlay/res/values/strings.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Flower icon overlay --> - <string name="icon_shape_flower_overlay" translatable="false">Flower</string> + <!-- Vessel icon overlay --> + <string name="icon_shape_vessel_overlay" translatable="false">Vessel</string> </resources> diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 20850af97429..02ab60b05bca 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -201,7 +201,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private final MainHandler mMainHandler; - private final SystemActionPerformer mSystemActionPerformer; + // Lazily initialized - access through getSystemActionPerfomer() + private SystemActionPerformer mSystemActionPerformer; private MagnificationController mMagnificationController; @@ -299,8 +300,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class); mPackageManager = mContext.getPackageManager(); mSecurityPolicy = new AccessibilitySecurityPolicy(mContext, this); - mSystemActionPerformer = - new SystemActionPerformer(mContext, mWindowManagerService, null, this); mA11yWindowManager = new AccessibilityWindowManager(mLock, mMainHandler, mWindowManagerService, this, mSecurityPolicy, this); mA11yDisplayListener = new AccessibilityDisplayListener(mContext, mMainHandler); @@ -677,7 +676,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mSecurityPolicy.enforceCallerIsRecentsOrHasPermission( Manifest.permission.MANAGE_ACCESSIBILITY, FUNCTION_REGISTER_SYSTEM_ACTION); - mSystemActionPerformer.registerSystemAction(actionId, action); + getSystemActionPerformer().registerSystemAction(actionId, action); } /** @@ -690,7 +689,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mSecurityPolicy.enforceCallerIsRecentsOrHasPermission( Manifest.permission.MANAGE_ACCESSIBILITY, FUNCTION_UNREGISTER_SYSTEM_ACTION); - mSystemActionPerformer.unregisterSystemAction(actionId); + getSystemActionPerformer().unregisterSystemAction(actionId); + } + + private SystemActionPerformer getSystemActionPerformer() { + if (mSystemActionPerformer == null) { + mSystemActionPerformer = + new SystemActionPerformer(mContext, mWindowManagerService, null, this); + } + return mSystemActionPerformer; } @Override @@ -802,7 +809,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub synchronized (mLock) { mUiAutomationManager.registerUiTestAutomationServiceLocked(owner, serviceClient, mContext, accessibilityServiceInfo, sIdCounter++, mMainHandler, - mSecurityPolicy, this, mWindowManagerService, mSystemActionPerformer, + mSecurityPolicy, this, mWindowManagerService, getSystemActionPerformer(), mA11yWindowManager, flags); onUserStateChangedLocked(getCurrentUserStateLocked()); } @@ -1522,7 +1529,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (service == null) { service = new AccessibilityServiceConnection(userState, mContext, componentName, installedService, sIdCounter++, mMainHandler, mLock, mSecurityPolicy, - this, mWindowManagerService, mSystemActionPerformer, + this, mWindowManagerService, getSystemActionPerformer(), mA11yWindowManager, mActivityTaskManagerService); } else if (userState.mBoundServices.contains(service)) { continue; @@ -2804,7 +2811,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub userState, mContext, COMPONENT_NAME, info, sIdCounter++, mMainHandler, mLock, mSecurityPolicy, AccessibilityManagerService.this, mWindowManagerService, - mSystemActionPerformer, mA11yWindowManager, mActivityTaskManagerService) { + getSystemActionPerformer(), mA11yWindowManager, mActivityTaskManagerService) { @Override public boolean supportsFlagForNotImportantViews(AccessibilityServiceInfo info) { return true; diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java index a1fc3fa1857d..35054991d3ff 100644 --- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java +++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java @@ -85,7 +85,6 @@ public class SystemActionPerformer { private final AccessibilityAction mLegacyNotificationsAction; private final AccessibilityAction mLegacyQuickSettingsAction; private final AccessibilityAction mLegacyPowerDialogAction; - private final AccessibilityAction mLegacyToggleSplitScreenAction; private final AccessibilityAction mLegacyLockScreenAction; private final AccessibilityAction mLegacyTakeScreenshotAction; @@ -142,10 +141,6 @@ public class SystemActionPerformer { AccessibilityService.GLOBAL_ACTION_POWER_DIALOG, mContext.getResources().getString( R.string.accessibility_system_action_power_dialog_label)); - mLegacyToggleSplitScreenAction = new AccessibilityAction( - AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN, - mContext.getResources().getString( - R.string.accessibility_system_action_toggle_split_screen_label)); mLegacyLockScreenAction = new AccessibilityAction( AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN, mContext.getResources().getString( @@ -235,10 +230,6 @@ public class SystemActionPerformer { systemActions.add(mLegacyPowerDialogAction); } if (!mRegisteredSystemActions.containsKey( - AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)) { - systemActions.add(mLegacyToggleSplitScreenAction); - } - if (!mRegisteredSystemActions.containsKey( AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN)) { systemActions.add(mLegacyLockScreenAction); } diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java index bc38fbf50000..4fee672a8803 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java @@ -566,6 +566,7 @@ public class TouchExplorer extends BaseEventStreamTransformation // a given distance perform a drag. mState.startDragging(); mDraggingPointerId = pointerId; + adjustEventLocationForDrag(event); event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags()); mDispatcher.sendMotionEvent( event, MotionEvent.ACTION_DOWN, rawEvent, pointerIdBits, policyFlags); @@ -793,10 +794,6 @@ public class TouchExplorer extends BaseEventStreamTransformation */ private void handleMotionEventStateDelegating( MotionEvent event, MotionEvent rawEvent, int policyFlags) { - if (mGestureDetector.isMultiFingerGesturesEnabled()) { - // Multi-finger gestures conflict with this functionality. - return; - } switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { Slog.e(LOG_TAG, "Delegating state can only be reached if " diff --git a/services/art-profile b/services/art-profile index e2974a1b7ae3..559356bdd1f5 100644 --- a/services/art-profile +++ b/services/art-profile @@ -32290,7 +32290,6 @@ HPLcom/android/server/pm/permission/BasePermission;->generatePermissionInfo(Ljav HSPLcom/android/server/pm/permission/BasePermission;->getName()Ljava/lang/String; HSPLcom/android/server/pm/permission/BasePermission;->getProtectionLevel()I HSPLcom/android/server/pm/permission/BasePermission;->getSourcePackageName()Ljava/lang/String; -HSPLcom/android/server/pm/permission/BasePermission;->getSourcePackageSetting()Lcom/android/server/pm/PackageSettingBase; PLcom/android/server/pm/permission/BasePermission;->getUid()I HSPLcom/android/server/pm/permission/BasePermission;->isAppOp()Z HSPLcom/android/server/pm/permission/BasePermission;->isAppPredictor()Z @@ -32329,7 +32328,6 @@ HSPLcom/android/server/pm/permission/BasePermission;->readLPw(Ljava/util/Map;Lor HSPLcom/android/server/pm/permission/BasePermission;->setGids([IZ)V HSPLcom/android/server/pm/permission/BasePermission;->setPermission(Landroid/content/pm/parsing/ComponentParseUtils$ParsedPermission;)V PLcom/android/server/pm/permission/BasePermission;->setPermission(Landroid/content/pm/parsing/component/ParsedPermission;)V -HSPLcom/android/server/pm/permission/BasePermission;->setSourcePackageSetting(Lcom/android/server/pm/PackageSettingBase;)V HSPLcom/android/server/pm/permission/BasePermission;->updateDynamicPermission(Ljava/util/Collection;)V HSPLcom/android/server/pm/permission/BasePermission;->writeLPr(Lorg/xmlpull/v1/XmlSerializer;)V HSPLcom/android/server/pm/permission/DefaultPermissionGrantPolicy$1;-><init>(Lcom/android/server/pm/permission/DefaultPermissionGrantPolicy;Landroid/os/Looper;)V diff --git a/services/art-profile-boot b/services/art-profile-boot index fe4178ac4a50..addc906fc86b 100644 --- a/services/art-profile-boot +++ b/services/art-profile-boot @@ -171,7 +171,6 @@ Lcom/android/server/pm/PackageUsage;->readToken(Ljava/io/InputStream;Ljava/lang/ Lcom/android/server/pm/PackageUsage;->readVersion1LP(Ljava/util/Map;Ljava/io/InputStream;Ljava/lang/StringBuffer;)V Lcom/android/server/pm/PackageUsage;->parseAsLong(Ljava/lang/String;)J Lcom/android/server/pm/CompilerStats;->read(Ljava/io/Reader;)Z -Lcom/android/server/pm/permission/BasePermission;->getSourcePackageSetting()Lcom/android/server/pm/PackageSettingBase; Lcom/android/server/pm/permission/PermissionManagerService;->updatePermissionSourcePackage(Ljava/lang/String;Landroid/content/pm/PackageParser$Package;)Z Lcom/android/server/pm/permission/BasePermission;->isDynamic()Z Lcom/android/server/pm/permission/PermissionManagerService;->cacheBackgroundToForegoundPermissionMapping()V diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java index a86d34d4eb3e..79c9efa48d73 100644 --- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java +++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java @@ -319,9 +319,10 @@ public final class InlineSuggestionFactory { } @Override - public void onContent(SurfaceControlViewHost.SurfacePackage surface) + public void onContent(SurfaceControlViewHost.SurfacePackage surface, int width, + int height) throws RemoteException { - callback.onContent(surface); + callback.onContent(surface, width, height); surface.release(); } diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 992e98473ae7..dc35c774f71e 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -318,6 +318,9 @@ public class UserBackupManagerService { private static final String SERIAL_ID_FILE = "serial_id"; + private static final String SKIP_USER_FACING_DATA = "backup_skip_user_facing_data"; + private static final String WALLPAPER_PACKAGE = "com.android.wallpaperbackup"; + private final @UserIdInt int mUserId; private final BackupAgentTimeoutParameters mAgentTimeoutParameters; private final TransportManager mTransportManager; @@ -3553,6 +3556,40 @@ public class UserBackupManagerService { } } + /** + * We want to skip backup/restore of certain packages if 'backup_skip_user_facing_data' is + * set to true in secure settings. See b/153940088 for details. + * + * TODO(b/154822946): Remove this logic in the next release. + */ + public List<PackageInfo> filterUserFacingPackages(List<PackageInfo> packages) { + if (!shouldSkipUserFacingData()) { + return packages; + } + + List<PackageInfo> filteredPackages = new ArrayList<>(packages.size()); + for (PackageInfo packageInfo : packages) { + if (!shouldSkipPackage(packageInfo.packageName)) { + filteredPackages.add(packageInfo); + } else { + Slog.i(TAG, "Will skip backup/restore for " + packageInfo.packageName); + } + } + + return filteredPackages; + } + + @VisibleForTesting + public boolean shouldSkipUserFacingData() { + return Settings.Secure.getInt(mContext.getContentResolver(), SKIP_USER_FACING_DATA, + /* def */ 0) != 0; + } + + @VisibleForTesting + public boolean shouldSkipPackage(String packageName) { + return WALLPAPER_PACKAGE.equals(packageName); + } + private void updateStateForTransport(String newTransportName) { // Publish the name change Settings.Secure.putStringForUser(mContext.getContentResolver(), diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java index f7f01387cf78..738dd9bf0f0d 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java +++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java @@ -61,6 +61,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -131,7 +132,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba private UserBackupManagerService mUserBackupManagerService; private final Object mCancelLock = new Object(); - ArrayList<PackageInfo> mPackages; + List<PackageInfo> mPackages; PackageInfo mCurrentPackage; boolean mUpdateSchedule; CountDownLatch mLatch; @@ -249,6 +250,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba null); } } + + mPackages = backupManagerService.filterUserFacingPackages(mPackages); } private void registerTask() { diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java index e434be648dcb..12113fea12a4 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -270,6 +270,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } } + mAcceptSet = backupManagerService.filterUserFacingPackages(mAcceptSet); + if (MORE_DEBUG) { Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size()); for (PackageInfo info : mAcceptSet) { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 552331ede99b..e4eb585e989d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -18,6 +18,14 @@ package com.android.server; import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK; +import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK; +import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT; +import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS; +import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS; +import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS; +import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS; +import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.NETID_UNSET; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; @@ -72,6 +80,7 @@ import android.net.ConnectionInfo; import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; import android.net.ConnectivityDiagnosticsManager.DataStallReport; import android.net.ConnectivityManager; +import android.net.DataStallReportParcelable; import android.net.ICaptivePortal; import android.net.IConnectivityDiagnosticsCallback; import android.net.IConnectivityManager; @@ -108,6 +117,7 @@ import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; import android.net.NetworkState; +import android.net.NetworkTestResultParcelable; import android.net.NetworkUtils; import android.net.NetworkWatchlistManager; import android.net.PrivateDnsConfigParcel; @@ -2820,14 +2830,6 @@ public class ConnectivityService extends IConnectivityManager.Stub handleNetworkTested(nai, results.mTestResult, (results.mRedirectUrl == null) ? "" : results.mRedirectUrl); - - // Invoke ConnectivityReport generation for this Network test event. - final Message m = - mConnectivityDiagnosticsHandler.obtainMessage( - ConnectivityDiagnosticsHandler.EVENT_NETWORK_TESTED, - new ConnectivityReportEvent(results.mTimestampMillis, nai)); - m.setData(msg.getData()); - mConnectivityDiagnosticsHandler.sendMessage(m); break; } case EVENT_PROVISIONING_NOTIFICATION: { @@ -3006,23 +3008,33 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) { - notifyNetworkTestedWithExtras(testResult, redirectUrl, SystemClock.elapsedRealtime(), - PersistableBundle.EMPTY); + // Legacy version of notifyNetworkTestedWithExtras. + // Would only be called if the system has a NetworkStack module older than the + // framework, which does not happen in practice. } @Override - public void notifyNetworkTestedWithExtras( - int testResult, - @Nullable String redirectUrl, - long timestampMillis, - @NonNull PersistableBundle extras) { - final Message msg = - mTrackerHandler.obtainMessage( - EVENT_NETWORK_TESTED, - new NetworkTestedResults( - mNetId, testResult, timestampMillis, redirectUrl)); - msg.setData(new Bundle(extras)); + public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) { + final Message msg = mTrackerHandler.obtainMessage( + EVENT_NETWORK_TESTED, + new NetworkTestedResults( + mNetId, p.result, p.timestampMillis, p.redirectUrl)); mTrackerHandler.sendMessage(msg); + + // Invoke ConnectivityReport generation for this Network test event. + final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId); + if (nai == null) return; + final Message m = mConnectivityDiagnosticsHandler.obtainMessage( + ConnectivityDiagnosticsHandler.EVENT_NETWORK_TESTED, + new ConnectivityReportEvent(p.timestampMillis, nai)); + + final PersistableBundle extras = new PersistableBundle(); + extras.putInt(KEY_NETWORK_VALIDATION_RESULT, p.result); + extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded); + extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted); + + m.setData(new Bundle(extras)); + mConnectivityDiagnosticsHandler.sendMessage(m); } @Override @@ -3071,12 +3083,25 @@ public class ConnectivityService extends IConnectivityManager.Stub } @Override - public void notifyDataStallSuspected( - long timestampMillis, int detectionMethod, PersistableBundle extras) { - final Message msg = - mConnectivityDiagnosticsHandler.obtainMessage( - ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, - detectionMethod, mNetId, timestampMillis); + public void notifyDataStallSuspected(DataStallReportParcelable p) { + final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( + ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, + p.detectionMethod, mNetId, p.timestampMillis); + + final PersistableBundle extras = new PersistableBundle(); + switch (p.detectionMethod) { + case DETECTION_METHOD_DNS_EVENTS: + extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts); + break; + case DETECTION_METHOD_TCP_METRICS: + extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate); + extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, + p.tcpMetricsCollectionPeriodMillis); + break; + default: + log("Unknown data stall detection method, ignoring: " + p.detectionMethod); + return; + } msg.setData(new Bundle(extras)); // NetworkStateTrackerHandler currently doesn't take any actions based on data diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java index b6bbe1912a16..b09b2605a791 100644 --- a/services/core/java/com/android/server/DynamicSystemService.java +++ b/services/core/java/com/android/server/DynamicSystemService.java @@ -51,7 +51,7 @@ public class DynamicSystemService extends IDynamicSystemService.Stub { mContext = context; } - private IGsiService getGsiService() throws RemoteException { + private IGsiService getGsiService() { checkPermission(); if (mGsiService != null) { return mGsiService; @@ -60,8 +60,7 @@ public class DynamicSystemService extends IDynamicSystemService.Stub { } private void checkPermission() { - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires MANAGE_DYNAMIC_SYSTEM permission"); } @@ -147,12 +146,12 @@ public class DynamicSystemService extends IDynamicSystemService.Stub { } @Override - public boolean isInUse() throws RemoteException { + public boolean isInUse() { return SystemProperties.getBoolean("ro.gsid.image_running", false); } @Override - public boolean isInstalled() throws RemoteException { + public boolean isInstalled() { boolean installed = SystemProperties.getBoolean("gsid.image_installed", false); Slog.i(TAG, "isInstalled(): " + installed); return installed; diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 58972a5346c7..425a0452b6b8 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -117,6 +117,7 @@ public class Watchdog extends Thread { "android.hardware.graphics.allocator@2.0::IAllocator", "android.hardware.graphics.composer@2.1::IComposer", "android.hardware.health@2.0::IHealth", + "android.hardware.light@2.0::ILight", "android.hardware.media.c2@1.0::IComponentStore", "android.hardware.media.omx@1.0::IOmx", "android.hardware.media.omx@1.0::IOmxStore", diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index b647818e3f7a..090ac5467c68 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -16,7 +16,6 @@ package com.android.server.am; -import android.app.ActivityManager; import android.bluetooth.BluetoothActivityEnergyInfo; import android.content.ContentResolver; import android.content.Context; @@ -376,9 +375,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub /** @param state Process state from ActivityManager.java. */ void noteUidProcessState(int uid, int state) { synchronized (mStats) { - FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, - ActivityManager.processStateAmToProto(state)); - mStats.noteUidProcessStateLocked(uid, state); } } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index c9ee47278796..e869e5799273 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -3639,17 +3639,22 @@ public final class ProcessList { final int packageCount = app.pkgList.size(); for (int j = 0; j < packageCount; j++) { final String packageName = app.pkgList.keyAt(j); - if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { - try { - final ApplicationInfo ai = AppGlobals.getPackageManager() - .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); - if (ai != null) { - app.thread.scheduleApplicationInfoChanged(ai); - } - } catch (RemoteException e) { - Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", - packageName, app)); + if (!updateFrameworkRes && !packagesToUpdate.contains(packageName)) { + continue; + } + try { + final ApplicationInfo ai = AppGlobals.getPackageManager() + .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); + if (ai == null) { + continue; } + app.thread.scheduleApplicationInfoChanged(ai); + if (ai.packageName.equals(app.info.packageName)) { + app.info = ai; + } + } catch (RemoteException e) { + Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", + packageName, app)); } } } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index a1ec07cda8a8..fc6931d6ede2 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -86,7 +86,7 @@ class ProcessRecord implements WindowProcessListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessRecord" : TAG_AM; private final ActivityManagerService mService; // where we came from - final ApplicationInfo info; // all about the first app in the process + volatile ApplicationInfo info; // all about the first app in the process final ProcessInfo processInfo; // if non-null, process-specific manifest info final boolean isolated; // true if this is a special isolated process final boolean appZygote; // true if this is forked from the app zygote diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index ee4697f37f52..de9b02ffd636 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -4133,9 +4133,6 @@ public class AppOpsService extends IAppOpsService.Stub { throws NumberFormatException, XmlPullParserException, IOException { int opCode = Integer.parseInt(parser.getAttributeValue(null, "n")); - if (isIgnoredAppOp(opCode)) { - return; - } Op op = new Op(uidState, pkgName, opCode, uidState.uid); final int mode = XmlUtils.readIntAttribute(parser, "m", @@ -4170,16 +4167,6 @@ public class AppOpsService extends IAppOpsService.Stub { ops.put(op.op, op); } - //TODO(b/149995538): Remove once this has reached all affected devices - private static boolean isIgnoredAppOp(int op) { - switch (op) { - case AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE: - return true; - default: - return false; - } - } - void writeState() { synchronized (mFile) { FileOutputStream stream; diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index d49b590b8a4d..70fbca5b4798 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -1504,11 +1504,17 @@ public class BiometricService extends SystemService { try { switch (reason) { case BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED: - mKeyStore.addAuthToken(credentialAttestation); + if (credentialAttestation != null) { + mKeyStore.addAuthToken(credentialAttestation); + } else { + Slog.e(TAG, "Credential confirmed but attestation is null"); + } case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED: case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED: if (mCurrentAuthSession.mTokenEscrow != null) { mKeyStore.addAuthToken(mCurrentAuthSession.mTokenEscrow); + } else { + Slog.e(TAG, "mTokenEscrow is null"); } mCurrentAuthSession.mClientReceiver.onAuthenticationSucceeded( Utils.getAuthenticationTypeForResult(reason)); diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index c8e5f6c8f53b..8fb384070e25 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -16,12 +16,14 @@ package com.android.server.display; +import android.annotation.Nullable; import android.content.Context; import android.database.ContentObserver; import android.graphics.SurfaceTexture; import android.os.Handler; import android.os.IBinder; import android.provider.Settings; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Slog; import android.view.Display; @@ -54,6 +56,10 @@ import java.util.regex.Pattern; * {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be * formatted as follows: * <pre> + * [display1];[display2];... + * </pre> + * with each display specified as: + * <pre> * [mode1]|[mode2]|...,[flag1],[flag2],... * </pre> * with each mode specified as: @@ -63,22 +69,56 @@ import java.util.regex.Pattern; * Supported flags: * <ul> * <li><pre>secure</pre>: creates a secure display</li> + * <li><pre>own_content_only</pre>: only shows this display's own content</li> + * <li><pre>should_show_system_decorations</pre>: supports system decorations</li> * </ul> - * </p> + * </p><p> + * Example: + * <ul> + * <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li> + * <li><code>1920x1080/320,secure;1280x720/213</code>: make two overlays, the first at 1080p and + * secure; the second at 720p.</li> + * <li><code>1920x1080/320|3840x2160/640</code>: make one overlay that is 1920x1080 at + * 213dpi by default, but can also be upscaled to 3840x2160 at 640dpi by the system if the + * display device allows.</li> + * <li>If the value is empty, then no overlay display devices are created.</li> + * </ul></p> */ final class OverlayDisplayAdapter extends DisplayAdapter { static final String TAG = "OverlayDisplayAdapter"; static final boolean DEBUG = false; + /** + * When this flag is set, the overlay display is considered secure. + * @see DisplayDeviceInfo#FLAG_SECURE + */ + private static final String OVERLAY_DISPLAY_FLAG_SECURE = "secure"; + + /** + * When this flag is set, only show this display's own content; do not mirror the content of + * another display. + * @see DisplayDeviceInfo#FLAG_OWN_CONTENT_ONLY + */ + private static final String OVERLAY_DISPLAY_FLAG_OWN_CONTENT_ONLY = "own_content_only"; + + /** + * When this flag is set, the overlay display should support system decorations. + * @see DisplayDeviceInfo#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS + */ + private static final String OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = + "should_show_system_decorations"; + private static final int MIN_WIDTH = 100; private static final int MIN_HEIGHT = 100; private static final int MAX_WIDTH = 4096; private static final int MAX_HEIGHT = 4096; - private static final Pattern DISPLAY_PATTERN = - Pattern.compile("([^,]+)(,[a-z]+)*"); - private static final Pattern MODE_PATTERN = - Pattern.compile("(\\d+)x(\\d+)/(\\d+)"); + private static final String DISPLAY_SPLITTER = ";"; + private static final String MODE_SPLITTER = "\\|"; + private static final String FLAG_SPLITTER = ","; + + private static final Pattern DISPLAY_PATTERN = Pattern.compile("([^,]+)(,[,_a-z]+)*"); + private static final Pattern MODE_PATTERN = Pattern.compile("(\\d+)x(\\d+)/(\\d+)"); // Unique id prefix for overlay displays. private static final String UNIQUE_ID_PREFIX = "overlay:"; @@ -154,7 +194,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { } int count = 0; - for (String part : value.split(";")) { + for (String part : value.split(DISPLAY_SPLITTER)) { Matcher displayMatcher = DISPLAY_PATTERN.matcher(part); if (displayMatcher.matches()) { if (count >= 4) { @@ -164,7 +204,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { String modeString = displayMatcher.group(1); String flagString = displayMatcher.group(2); ArrayList<OverlayMode> modes = new ArrayList<>(); - for (String mode : modeString.split("\\|")) { + for (String mode : modeString.split(MODE_SPLITTER)) { Matcher modeMatcher = MODE_PATTERN.matcher(mode); if (modeMatcher.matches()) { try { @@ -192,12 +232,13 @@ final class OverlayDisplayAdapter extends DisplayAdapter { com.android.internal.R.string.display_manager_overlay_display_name, number); int gravity = chooseOverlayGravity(number); - boolean secure = flagString != null && flagString.contains(",secure"); + OverlayFlags flags = OverlayFlags.parseFlags(flagString); Slog.i(TAG, "Showing overlay display device #" + number - + ": name=" + name + ", modes=" + Arrays.toString(modes.toArray())); + + ": name=" + name + ", modes=" + Arrays.toString(modes.toArray()) + + ", flags=" + flags); - mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, secure, number)); + mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, flags, number)); continue; } } @@ -223,7 +264,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { private final String mName; private final float mRefreshRate; private final long mDisplayPresentationDeadlineNanos; - private final boolean mSecure; + private final OverlayFlags mFlags; private final List<OverlayMode> mRawModes; private final Display.Mode[] mModes; private final int mDefaultMode; @@ -234,16 +275,15 @@ final class OverlayDisplayAdapter extends DisplayAdapter { private DisplayDeviceInfo mInfo; private int mActiveMode; - public OverlayDisplayDevice(IBinder displayToken, String name, + OverlayDisplayDevice(IBinder displayToken, String name, List<OverlayMode> modes, int activeMode, int defaultMode, float refreshRate, long presentationDeadlineNanos, - boolean secure, int state, - SurfaceTexture surfaceTexture, int number) { + OverlayFlags flags, int state, SurfaceTexture surfaceTexture, int number) { super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number); mName = name; mRefreshRate = refreshRate; mDisplayPresentationDeadlineNanos = presentationDeadlineNanos; - mSecure = secure; + mFlags = flags; mState = state; mSurfaceTexture = surfaceTexture; mRawModes = modes; @@ -304,9 +344,15 @@ final class OverlayDisplayAdapter extends DisplayAdapter { mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos + 1000000000L / (int) mRefreshRate; // display's deadline + 1 frame mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION; - if (mSecure) { + if (mFlags.mSecure) { mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE; } + if (mFlags.mOwnContentOnly) { + mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; + } + if (mFlags.mShouldShowSystemDecorations) { + mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; + } mInfo.type = Display.TYPE_OVERLAY; mInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL; mInfo.state = mState; @@ -363,19 +409,23 @@ final class OverlayDisplayAdapter extends DisplayAdapter { private final String mName; private final List<OverlayMode> mModes; private final int mGravity; - private final boolean mSecure; + private final OverlayFlags mFlags; private final int mNumber; private OverlayDisplayWindow mWindow; private OverlayDisplayDevice mDevice; private int mActiveMode; - public OverlayDisplayHandle(String name, List<OverlayMode> modes, int gravity, - boolean secure, int number) { + OverlayDisplayHandle( + String name, + List<OverlayMode> modes, + int gravity, + OverlayFlags flags, + int number) { mName = name; mModes = modes; mGravity = gravity; - mSecure = secure; + mFlags = flags; mNumber = number; mActiveMode = 0; @@ -405,10 +455,10 @@ final class OverlayDisplayAdapter extends DisplayAdapter { public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate, long presentationDeadlineNanos, int state) { synchronized (getSyncRoot()) { - IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure); + IBinder displayToken = SurfaceControl.createDisplay(mName, mFlags.mSecure); mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode, DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos, - mSecure, state, surfaceTexture, mNumber) { + mFlags, state, surfaceTexture, mNumber) { @Override public void onModeChangedLocked(int index) { onActiveModeChangedLocked(index); @@ -446,7 +496,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { pw.println(" mModes=" + Arrays.toString(mModes.toArray())); pw.println(" mActiveMode=" + mActiveMode); pw.println(" mGravity=" + mGravity); - pw.println(" mSecure=" + mSecure); + pw.println(" mFlags=" + mFlags); pw.println(" mNumber=" + mNumber); // Try to dump the window state. @@ -463,8 +513,8 @@ final class OverlayDisplayAdapter extends DisplayAdapter { public void run() { OverlayMode mode = mModes.get(mActiveMode); OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(), - mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, mSecure, - OverlayDisplayHandle.this); + mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, + mFlags.mSecure, OverlayDisplayHandle.this); window.show(); synchronized (getSyncRoot()) { @@ -531,4 +581,60 @@ final class OverlayDisplayAdapter extends DisplayAdapter { .toString(); } } + + /** Represents the flags of the overlay display. */ + private static final class OverlayFlags { + /** See {@link #OVERLAY_DISPLAY_FLAG_SECURE}. */ + final boolean mSecure; + + /** See {@link #OVERLAY_DISPLAY_FLAG_OWN_CONTENT_ONLY}. */ + final boolean mOwnContentOnly; + + /** See {@link #OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS}. */ + final boolean mShouldShowSystemDecorations; + + OverlayFlags( + boolean secure, + boolean ownContentOnly, + boolean shouldShowSystemDecorations) { + mSecure = secure; + mOwnContentOnly = ownContentOnly; + mShouldShowSystemDecorations = shouldShowSystemDecorations; + } + + static OverlayFlags parseFlags(@Nullable String flagString) { + if (TextUtils.isEmpty(flagString)) { + return new OverlayFlags( + false /* secure */, + false /* ownContentOnly */, + false /* shouldShowSystemDecorations */); + } + + boolean secure = false; + boolean ownContentOnly = false; + boolean shouldShowSystemDecorations = false; + for (String flag: flagString.split(FLAG_SPLITTER)) { + if (OVERLAY_DISPLAY_FLAG_SECURE.equals(flag)) { + secure = true; + } + if (OVERLAY_DISPLAY_FLAG_OWN_CONTENT_ONLY.equals(flag)) { + ownContentOnly = true; + } + if (OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS.equals(flag)) { + shouldShowSystemDecorations = true; + } + } + return new OverlayFlags(secure, ownContentOnly, shouldShowSystemDecorations); + } + + @Override + public String toString() { + return new StringBuilder("{") + .append("secure=").append(mSecure) + .append(", ownContentOnly=").append(mOwnContentOnly) + .append(", shouldShowSystemDecorations=").append(mShouldShowSystemDecorations) + .append("}") + .toString(); + } + } } diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index 532045320988..5bc69943033e 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -62,6 +62,7 @@ final class DreamController { private final Listener mListener; private final IWindowManager mIWindowManager; private long mDreamStartTime; + private String mSavedStopReason; private final Intent mDreamingStartedIntent = new Intent(Intent.ACTION_DREAMING_STARTED) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -77,14 +78,15 @@ final class DreamController { public void run() { if (mCurrentDream != null && mCurrentDream.mBound && !mCurrentDream.mConnected) { Slog.w(TAG, "Bound dream did not connect in the time allotted"); - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "slow to connect"); } } }; private final Runnable mStopStubbornDreamRunnable = () -> { Slog.w(TAG, "Stubborn dream did not finish itself in the time allotted"); - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "slow to finish"); + mSavedStopReason = null; }; public DreamController(Context context, Handler handler, Listener listener) { @@ -116,7 +118,7 @@ final class DreamController { public void startDream(Binder token, ComponentName name, boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) { - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "starting new dream"); Trace.traceBegin(Trace.TRACE_TAG_POWER, "startDream"); try { @@ -141,12 +143,12 @@ final class DreamController { Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(userId))) { Slog.e(TAG, "Unable to bind dream service: " + intent); - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "bindService failed"); return; } } catch (SecurityException ex) { Slog.e(TAG, "Unable to bind dream service: " + intent, ex); - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "unable to bind service: SecExp."); return; } @@ -157,7 +159,7 @@ final class DreamController { } } - public void stopDream(boolean immediate) { + public void stopDream(boolean immediate, String reason) { if (mCurrentDream == null) { return; } @@ -173,6 +175,7 @@ final class DreamController { // Give the dream a moment to wake up and finish itself gently. mCurrentDream.mWakingGently = true; try { + mSavedStopReason = reason; mCurrentDream.mService.wakeUp(); mHandler.postDelayed(mStopStubbornDreamRunnable, DREAM_FINISH_TIMEOUT); return; @@ -186,7 +189,9 @@ final class DreamController { mCurrentDream = null; Slog.i(TAG, "Stopping dream: name=" + oldDream.mName + ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze - + ", userId=" + oldDream.mUserId); + + ", userId=" + oldDream.mUserId + + ", reason='" + reason + "'" + + (mSavedStopReason == null ? "" : "(from '" + mSavedStopReason + "')")); MetricsLogger.hidden(mContext, oldDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING); MetricsLogger.histogram(mContext, @@ -195,6 +200,7 @@ final class DreamController { mHandler.removeCallbacks(mStopUnconnectedDreamRunnable); mHandler.removeCallbacks(mStopStubbornDreamRunnable); + mSavedStopReason = null; if (oldDream.mSentStartBroadcast) { mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL); @@ -233,7 +239,7 @@ final class DreamController { mCurrentDream.mDreamingStartedCallback); } catch (RemoteException ex) { Slog.e(TAG, "The dream service died unexpectedly.", ex); - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "attach failed"); return; } @@ -287,7 +293,7 @@ final class DreamController { mHandler.post(() -> { mService = null; if (mCurrentDream == DreamRecord.this) { - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "binder died"); } }); } @@ -312,7 +318,7 @@ final class DreamController { mHandler.post(() -> { mService = null; if (mCurrentDream == DreamRecord.this) { - stopDream(true /*immediate*/); + stopDream(true /*immediate*/, "service disconnected"); } }); } diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index bcf262d97235..769956d797b0 100644 --- a/services/core/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -121,7 +121,7 @@ public final class DreamManagerService extends SystemService { public void onReceive(Context context, Intent intent) { writePulseGestureEnabled(); synchronized (mLock) { - stopDreamLocked(false /*immediate*/); + stopDreamLocked(false /*immediate*/, "user switched"); } } }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); @@ -180,7 +180,7 @@ public final class DreamManagerService extends SystemService { // for example when being undocked. long time = SystemClock.uptimeMillis(); mPowerManager.userActivity(time, false /*noChangeLights*/); - stopDreamInternal(false /*immediate*/); + stopDreamInternal(false /*immediate*/, "request awaken"); } private void finishSelfInternal(IBinder token, boolean immediate) { @@ -197,7 +197,7 @@ public final class DreamManagerService extends SystemService { // device may simply go to sleep. synchronized (mLock) { if (mCurrentDreamToken == token) { - stopDreamLocked(immediate); + stopDreamLocked(immediate, "finished self"); } } } @@ -218,9 +218,9 @@ public final class DreamManagerService extends SystemService { } } - private void stopDreamInternal(boolean immediate) { + private void stopDreamInternal(boolean immediate, String reason) { synchronized (mLock) { - stopDreamLocked(immediate); + stopDreamLocked(immediate, reason); } } @@ -373,7 +373,7 @@ public final class DreamManagerService extends SystemService { return; } - stopDreamLocked(true /*immediate*/); + stopDreamLocked(true /*immediate*/, "starting new dream"); Slog.i(TAG, "Entering dreamland."); @@ -392,7 +392,7 @@ public final class DreamManagerService extends SystemService { })); } - private void stopDreamLocked(final boolean immediate) { + private void stopDreamLocked(final boolean immediate, String reason) { if (mCurrentDreamToken != null) { if (immediate) { Slog.i(TAG, "Leaving dreamland."); @@ -408,7 +408,7 @@ public final class DreamManagerService extends SystemService { @Override public void run() { Slog.i(TAG, "Performing gentle wake from dream."); - mController.stopDream(immediate); + mController.stopDream(immediate, reason); } }); } @@ -696,7 +696,7 @@ public final class DreamManagerService extends SystemService { @Override public void stopDream(boolean immediate) { - stopDreamInternal(immediate); + stopDreamInternal(immediate, "requested stopDream"); } @Override diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index a358707a4346..3ff6ec1afa41 100755 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -32,6 +32,7 @@ import android.view.KeyCharacterMap; import android.view.KeyEvent; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; import com.android.server.hdmi.Constants.LocalActivePort; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; @@ -144,7 +145,8 @@ abstract class HdmiCecLocalDevice { // A collection of FeatureAction. // Note that access to this collection should happen in service thread. - private final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>(); + @VisibleForTesting + final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>(); private final Handler mHandler = new Handler() { @@ -544,6 +546,8 @@ abstract class HdmiCecLocalDevice { } else if (mService.isPowerStandbyOrTransient() && isPowerOnOrToggleCommand(message)) { mService.wakeUp(); return true; + } else if (!mService.isHdmiCecVolumeControlEnabled() && isVolumeOrMuteCommand(message)) { + return false; } final long downTime = SystemClock.uptimeMillis(); @@ -618,6 +622,16 @@ abstract class HdmiCecLocalDevice { || params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION); } + static boolean isVolumeOrMuteCommand(HdmiCecMessage message) { + byte[] params = message.getParams(); + return message.getOpcode() == Constants.MESSAGE_USER_CONTROL_PRESSED + && (params[0] == HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN + || params[0] == HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP + || params[0] == HdmiCecKeycode.CEC_KEYCODE_MUTE + || params[0] == HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION + || params[0] == HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION); + } + protected boolean handleTextViewOn(HdmiCecMessage message) { return false; } @@ -1038,6 +1052,9 @@ abstract class HdmiCecLocalDevice { @ServiceThreadOnly protected void sendVolumeKeyEvent(int keyCode, boolean isPressed) { assertRunOnServiceThread(); + if (!mService.isHdmiCecVolumeControlEnabled()) { + return; + } if (!HdmiCecKeycode.isVolumeKeycode(keyCode)) { Slog.w(TAG, "Not a volume key: " + keyCode); return; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index e5a08d3e79aa..611b8c69077d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -575,7 +575,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @ServiceThreadOnly protected boolean handleGiveAudioStatus(HdmiCecMessage message) { assertRunOnServiceThread(); - if (isSystemAudioControlFeatureEnabled()) { + if (isSystemAudioControlFeatureEnabled() && mService.isHdmiCecVolumeControlEnabled()) { reportAudioStatus(message.getSource()); } else { mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED); @@ -930,6 +930,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { void reportAudioStatus(int source) { assertRunOnServiceThread(); + if (!mService.isHdmiCecVolumeControlEnabled()) { + return; + } int volume = mService.getAudioManager().getStreamVolume(AudioManager.STREAM_MUSIC); boolean mute = mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index a702ce517f40..0ac4f9ee4c6d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -678,6 +678,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { @ServiceThreadOnly protected boolean handleReportAudioStatus(HdmiCecMessage message) { assertRunOnServiceThread(); + if (!mService.isHdmiCecVolumeControlEnabled()) { + return false; + } boolean mute = HdmiUtils.isAudioStatusMute(message); int volume = HdmiUtils.getAudioStatusVolume(message); @@ -987,7 +990,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } void setAudioStatus(boolean mute, int volume) { - if (!isSystemAudioActivated()) { + if (!isSystemAudioActivated() || !mService.isHdmiCecVolumeControlEnabled()) { return; } synchronized (mLock) { @@ -1009,7 +1012,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { // On initialization process, getAvrDeviceInfo() may return null and cause exception return; } - if (delta == 0 || !isSystemAudioActivated()) { + if (delta == 0 || !isSystemAudioActivated() || !mService.isHdmiCecVolumeControlEnabled()) { return; } @@ -1038,7 +1041,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { @ServiceThreadOnly void changeMute(boolean mute) { assertRunOnServiceThread(); - if (getAvrDeviceInfo() == null) { + if (getAvrDeviceInfo() == null || !mService.isHdmiCecVolumeControlEnabled()) { // On initialization process, getAvrDeviceInfo() may return null and cause exception return; } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index d9e30250ba2d..53f9ebcbd8dd 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -177,6 +177,10 @@ public class HdmiControlService extends SystemService { @GuardedBy("mLock") protected final ActiveSource mActiveSource = new ActiveSource(); + // Whether HDMI CEC volume control is enabled or not. + @GuardedBy("mLock") + private boolean mHdmiCecVolumeControlEnabled; + // Whether System Audio Mode is activated or not. @GuardedBy("mLock") private boolean mSystemAudioActivated = false; @@ -497,6 +501,8 @@ public class HdmiControlService extends SystemService { mPowerStatus = getInitialPowerStatus(); mProhibitMode = false; mHdmiControlEnabled = readBooleanSetting(Global.HDMI_CONTROL_ENABLED, true); + mHdmiCecVolumeControlEnabled = readBooleanSetting( + Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, true); mMhlInputChangeEnabled = readBooleanSetting(Global.MHL_INPUT_SWITCHING_ENABLED, true); if (mCecController == null) { @@ -646,6 +652,7 @@ public class HdmiControlService extends SystemService { ContentResolver resolver = getContext().getContentResolver(); String[] settings = new String[] { Global.HDMI_CONTROL_ENABLED, + Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, @@ -674,6 +681,9 @@ public class HdmiControlService extends SystemService { case Global.HDMI_CONTROL_ENABLED: setControlEnabled(enabled); break; + case Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED: + setHdmiCecVolumeControlEnabled(enabled); + break; case Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED: if (isTvDeviceEnabled()) { tv().setAutoWakeup(enabled); @@ -1273,7 +1283,9 @@ public class HdmiControlService extends SystemService { } void setAudioStatus(boolean mute, int volume) { - if (!isTvDeviceEnabled() || !tv().isSystemAudioActivated()) { + if (!isTvDeviceEnabled() + || !tv().isSystemAudioActivated() + || !isHdmiCecVolumeControlEnabled()) { return; } AudioManager audioManager = getAudioManager(); @@ -2187,6 +2199,24 @@ public class HdmiControlService extends SystemService { } @Override + public boolean isHdmiCecVolumeControlEnabled() { + enforceAccessPermission(); + return HdmiControlService.this.isHdmiCecVolumeControlEnabled(); + } + + @Override + public void setHdmiCecVolumeControlEnabled(final boolean isHdmiCecVolumeControlEnabled) { + enforceAccessPermission(); + runOnServiceThread(new Runnable() { + @Override + public void run() { + HdmiControlService.this.setHdmiCecVolumeControlEnabled( + isHdmiCecVolumeControlEnabled); + } + }); + } + + @Override public void reportAudioStatus(final int deviceType, final int volume, final int maxVolume, final boolean isMute) { enforceAccessPermission(); @@ -2250,6 +2280,7 @@ public class HdmiControlService extends SystemService { pw.println("mHdmiControlEnabled: " + mHdmiControlEnabled); pw.println("mMhlInputChangeEnabled: " + mMhlInputChangeEnabled); pw.println("mSystemAudioActivated: " + isSystemAudioActivated()); + pw.println("mHdmiCecVolumeControlEnabled " + mHdmiCecVolumeControlEnabled); pw.decreaseIndent(); pw.println("mMhlController: "); @@ -2982,6 +3013,29 @@ public class HdmiControlService extends SystemService { } } + void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) { + assertRunOnServiceThread(); + synchronized (mLock) { + mHdmiCecVolumeControlEnabled = isHdmiCecVolumeControlEnabled; + + boolean storedValue = readBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, + true); + if (storedValue != isHdmiCecVolumeControlEnabled) { + HdmiLogger.debug("Changing HDMI CEC volume control feature state: %s", + isHdmiCecVolumeControlEnabled); + writeBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, + isHdmiCecVolumeControlEnabled); + } + } + } + + boolean isHdmiCecVolumeControlEnabled() { + assertRunOnServiceThread(); + synchronized (mLock) { + return mHdmiCecVolumeControlEnabled; + } + } + boolean isProhibitMode() { synchronized (mLock) { return mProhibitMode; @@ -3022,8 +3076,12 @@ public class HdmiControlService extends SystemService { if (enabled) { enableHdmiControlService(); + setHdmiCecVolumeControlEnabled( + readBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, true)); return; } + + setHdmiCecVolumeControlEnabled(false); // Call the vendor handler before the service is disabled. invokeVendorCommandListenersOnControlStateChanged(false, HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index e6129b9b1f32..115899a2a518 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -1069,7 +1069,7 @@ public class InputManagerService extends IInputManager.Stub | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0, - intent, 0, null, UserHandle.CURRENT); + intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); Resources r = mContext.getResources(); Notification notification = diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 0d16ee0e1d5a..0b73e4f0e9b4 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -192,7 +192,6 @@ public final class MultiClientInputMethodManagerService { InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb) { try { - //TODO(b/137800469): support multi client IMEs. cb.onInlineSuggestionsUnsupported(); } catch (RemoteException e) { Slog.w(TAG, "Failed to call onInlineSuggestionsUnsupported.", e); diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index 393e8db96c01..2cae1d64ca34 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -360,7 +360,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { * Verify the UID and return the installer package name. * * @return the package name of the installer, or null if it cannot be determined or it is - * installed via adb. + * installed via adb. */ @Nullable private String getInstallerPackageName(Intent intent) { @@ -568,7 +568,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { try (PackageParser2 parser = mParserSupplier.get()) { ParsedPackage pkg = parser.parsePackage(installationPath, 0, false); int flags = PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_META_DATA; - pkg.setSigningDetails(ParsingPackageUtils.collectCertificates(pkg, false)); + // APK signatures is already verified elsewhere in PackageManager. We do not need to + // verify it again since it could cause a timeout for large APKs. + pkg.setSigningDetails( + ParsingPackageUtils.collectCertificates(pkg, /* skipVerify= */ true)); return PackageInfoUtils.generate( pkg, null, @@ -709,7 +712,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { // Filter out the rule provider packages that are not system apps. List<String> systemAppRuleProviders = new ArrayList<>(); - for (String ruleProvider: integrityRuleProviders) { + for (String ruleProvider : integrityRuleProviders) { if (isSystemApp(ruleProvider)) { systemAppRuleProviders.add(ruleProvider); } diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java index 0b9697840a1f..3a29622556cc 100644 --- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java +++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java @@ -33,29 +33,28 @@ import java.util.Map; /** * Provides a way to customize behavior for media key events. * <p> - * In order to override the implementation of the single/double/triple click or long press, + * In order to override the implementation of the single/double/triple tap or long press, * {@link #setOverriddenKeyEvents(int, int)} should be called for each key code with the * overridden {@link KeyEventType} bit value set, and the corresponding method, - * {@link #onSingleClick(KeyEvent)}, {@link #onDoubleClick(KeyEvent)}, - * {@link #onTripleClick(KeyEvent)}, {@link #onLongPress(KeyEvent)} should be implemented. + * {@link #onSingleTap(KeyEvent)}, {@link #onDoubleTap(KeyEvent)}, + * {@link #onTripleTap(KeyEvent)}, {@link #onLongPress(KeyEvent)} should be implemented. * <p> * Note: When instantiating this class, {@link MediaSessionService} will only use the constructor * without any parameters. */ -// TODO: Change API names from using "click" to "tap" // TODO: Move this class to apex/media/ public abstract class MediaKeyDispatcher { @IntDef(flag = true, value = { - KEY_EVENT_SINGLE_CLICK, - KEY_EVENT_DOUBLE_CLICK, - KEY_EVENT_TRIPLE_CLICK, + KEY_EVENT_SINGLE_TAP, + KEY_EVENT_DOUBLE_TAP, + KEY_EVENT_TRIPLE_TAP, KEY_EVENT_LONG_PRESS }) @Retention(RetentionPolicy.SOURCE) @interface KeyEventType {} - static final int KEY_EVENT_SINGLE_CLICK = 1 << 0; - static final int KEY_EVENT_DOUBLE_CLICK = 1 << 1; - static final int KEY_EVENT_TRIPLE_CLICK = 1 << 2; + static final int KEY_EVENT_SINGLE_TAP = 1 << 0; + static final int KEY_EVENT_DOUBLE_TAP = 1 << 1; + static final int KEY_EVENT_TRIPLE_TAP = 1 << 2; static final int KEY_EVENT_LONG_PRESS = 1 << 3; private Map<Integer, Integer> mOverriddenKeyEvents; @@ -110,16 +109,16 @@ public abstract class MediaKeyDispatcher { return mOverriddenKeyEvents; } - static boolean isSingleClickOverridden(@KeyEventType int overriddenKeyEvents) { - return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_SINGLE_CLICK) != 0; + static boolean isSingleTapOverridden(@KeyEventType int overriddenKeyEvents) { + return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_SINGLE_TAP) != 0; } - static boolean isDoubleClickOverridden(@KeyEventType int overriddenKeyEvents) { - return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_DOUBLE_CLICK) != 0; + static boolean isDoubleTapOverridden(@KeyEventType int overriddenKeyEvents) { + return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_DOUBLE_TAP) != 0; } - static boolean isTripleClickOverridden(@KeyEventType int overriddenKeyEvents) { - return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_TRIPLE_CLICK) != 0; + static boolean isTripleTapOverridden(@KeyEventType int overriddenKeyEvents) { + return (overriddenKeyEvents & MediaKeyDispatcher.KEY_EVENT_TRIPLE_TAP) != 0; } static boolean isLongPressOverridden(@KeyEventType int overriddenKeyEvents) { @@ -150,11 +149,11 @@ public abstract class MediaKeyDispatcher { } /** - * Customized implementation for single click event. Will be run if - * {@link #KEY_EVENT_SINGLE_CLICK} flag is on for the corresponding key code from + * Customized implementation for single tap event. Will be run if + * {@link #KEY_EVENT_SINGLE_TAP} flag is on for the corresponding key code from * {@link #getOverriddenKeyEvents()}. * - * It is considered a single click if only one {@link KeyEvent} with the same + * It is considered a single tap if only one {@link KeyEvent} with the same * {@link KeyEvent#getKeyCode()} is dispatched within * {@link ViewConfiguration#getMultiPressTimeout()} milliseconds. Change the * {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval. @@ -163,15 +162,15 @@ public abstract class MediaKeyDispatcher { * * @param keyEvent */ - void onSingleClick(KeyEvent keyEvent) { + void onSingleTap(KeyEvent keyEvent) { } /** - * Customized implementation for double click event. Will be run if - * {@link #KEY_EVENT_DOUBLE_CLICK} flag is on for the corresponding key code from + * Customized implementation for double tap event. Will be run if + * {@link #KEY_EVENT_DOUBLE_TAP} flag is on for the corresponding key code from * {@link #getOverriddenKeyEvents()}. * - * It is considered a double click if two {@link KeyEvent}s with the same + * It is considered a double tap if two {@link KeyEvent}s with the same * {@link KeyEvent#getKeyCode()} are dispatched within * {@link ViewConfiguration#getMultiPressTimeout()} milliseconds of each other. Change the * {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval. @@ -180,15 +179,15 @@ public abstract class MediaKeyDispatcher { * * @param keyEvent */ - void onDoubleClick(KeyEvent keyEvent) { + void onDoubleTap(KeyEvent keyEvent) { } /** - * Customized implementation for triple click event. Will be run if - * {@link #KEY_EVENT_TRIPLE_CLICK} flag is on for the corresponding key code from + * Customized implementation for triple tap event. Will be run if + * {@link #KEY_EVENT_TRIPLE_TAP} flag is on for the corresponding key code from * {@link #getOverriddenKeyEvents()}. * - * It is considered a triple click if three {@link KeyEvent}s with the same + * It is considered a triple tap if three {@link KeyEvent}s with the same * {@link KeyEvent#getKeyCode()} are dispatched within * {@link ViewConfiguration#getMultiPressTimeout()} milliseconds of each other. Change the * {@link android.provider.Settings.Secure#MULTI_PRESS_TIMEOUT} value to adjust the interval. @@ -197,7 +196,7 @@ public abstract class MediaKeyDispatcher { * * @param keyEvent */ - void onTripleClick(KeyEvent keyEvent) { + void onTripleTap(KeyEvent keyEvent) { } /** diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index d8bf9edee2b7..5e865e7cb715 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -1574,8 +1574,15 @@ class MediaRouter2ServiceImpl { } // Succeeded - notifySessionCreatedToRouter(matchingRequest.mRouterRecord, - toOriginalRequestId(uniqueRequestId), sessionInfo); + if (sessionInfo.isSystemSession() + && !matchingRequest.mRouterRecord.mHasModifyAudioRoutingPermission) { + notifySessionCreatedToRouter(matchingRequest.mRouterRecord, + toOriginalRequestId(uniqueRequestId), + mSystemProvider.getDefaultSessionInfo()); + } else { + notifySessionCreatedToRouter(matchingRequest.mRouterRecord, + toOriginalRequestId(uniqueRequestId), sessionInfo); + } mSessionToRouterMap.put(sessionInfo.getId(), routerRecord); } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 476c9f879ca2..bc0e8166fb42 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -18,6 +18,12 @@ package com.android.server.media; import static android.os.UserHandle.USER_ALL; +import static com.android.server.media.MediaKeyDispatcher.KEY_EVENT_LONG_PRESS; +import static com.android.server.media.MediaKeyDispatcher.isDoubleTapOverridden; +import static com.android.server.media.MediaKeyDispatcher.isLongPressOverridden; +import static com.android.server.media.MediaKeyDispatcher.isSingleTapOverridden; +import static com.android.server.media.MediaKeyDispatcher.isTripleTapOverridden; + import android.app.ActivityManager; import android.app.INotificationManager; import android.app.KeyguardManager; @@ -105,7 +111,7 @@ public class MediaSessionService extends SystemService implements Monitor { private static final int SESSION_CREATION_LIMIT_PER_UID = 100; private static final int LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout() + /* Buffer for delayed delivery of key event */ 50; - private static final int MULTI_PRESS_TIMEOUT = ViewConfiguration.getMultiPressTimeout(); + private static final int MULTI_TAP_TIMEOUT = ViewConfiguration.getMultiPressTimeout(); private final Context mContext; private final SessionManagerImpl mSessionManagerImpl; @@ -1101,9 +1107,12 @@ public class MediaSessionService extends SystemService implements Monitor { "android.media.AudioService.WAKELOCK_ACQUIRED"; private static final int WAKELOCK_RELEASE_ON_FINISHED = 1980; // magic number - private KeyEvent mPendingFirstDownKeyEvent = null; + private KeyEvent mTrackingFirstDownKeyEvent = null; private boolean mIsLongPressing = false; private Runnable mLongPressTimeoutRunnable = null; + private int mMultiTapCount = 0; + private int mMultiTapKeyCode = 0; + private Runnable mMultiTapTimeoutRunnable = null; @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, @@ -2117,10 +2126,12 @@ public class MediaSessionService extends SystemService implements Monitor { } // A long press is determined by: - // 1) A KeyEvent with KeyEvent.ACTION_DOWN and repeat count of 0, followed by - // 2) A KeyEvent with KeyEvent.ACTION_DOWN and repeat count of 1 and FLAG_LONG_PRESS within - // ViewConfiguration.getLongPressTimeout(). - // TODO: Add description about what a click is determined by. + // 1) A KeyEvent.ACTION_DOWN KeyEvent and repeat count of 0, followed by + // 2) A KeyEvent.ACTION_DOWN KeyEvent with the same key code, a repeat count of 1, and + // FLAG_LONG_PRESS received within ViewConfiguration.getLongPressTimeout(). + // A tap is determined by: + // 1) A KeyEvent.ACTION_DOWN KeyEvent followed by + // 2) A KeyEvent.ACTION_UP KeyEvent with the same key code. private void handleKeyEventLocked(String packageName, int pid, int uid, boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) { if (keyEvent.isCanceled()) { @@ -2129,61 +2140,121 @@ public class MediaSessionService extends SystemService implements Monitor { int overriddenKeyEvents = (mCustomMediaKeyDispatcher == null) ? 0 : mCustomMediaKeyDispatcher.getOverriddenKeyEvents().get(keyEvent.getKeyCode()); - cancelPendingIfNeeded(keyEvent); - if (!needPending(keyEvent, overriddenKeyEvents)) { + cancelTrackingIfNeeded(packageName, pid, uid, asSystemService, keyEvent, needWakeLock, + overriddenKeyEvents); + if (!needTracking(keyEvent, overriddenKeyEvents)) { dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService, keyEvent, needWakeLock); return; } if (isFirstDownKeyEvent(keyEvent)) { - mPendingFirstDownKeyEvent = keyEvent; + mTrackingFirstDownKeyEvent = keyEvent; mIsLongPressing = false; return; } + // Long press is always overridden here, otherwise the key event would have been already + // handled if (isFirstLongPressKeyEvent(keyEvent)) { mIsLongPressing = true; } if (mIsLongPressing) { handleLongPressLocked(keyEvent, needWakeLock, overriddenKeyEvents); - } else if (keyEvent.getAction() == KeyEvent.ACTION_UP) { - mPendingFirstDownKeyEvent = null; - // TODO: Replace this with code to determine whether - // single/double/triple click and run custom implementations, - // if they exist. - dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService, - keyEvent, needWakeLock); + return; + } + + if (keyEvent.getAction() == KeyEvent.ACTION_UP) { + mTrackingFirstDownKeyEvent = null; + if (shouldTrackForMultipleTapsLocked(overriddenKeyEvents)) { + if (mMultiTapCount == 0) { + mMultiTapTimeoutRunnable = createSingleTapRunnable(packageName, pid, uid, + asSystemService, keyEvent, needWakeLock, + isSingleTapOverridden(overriddenKeyEvents)); + if (isSingleTapOverridden(overriddenKeyEvents) + && !isDoubleTapOverridden(overriddenKeyEvents) + && !isTripleTapOverridden(overriddenKeyEvents)) { + mMultiTapTimeoutRunnable.run(); + } else { + mHandler.postDelayed(mMultiTapTimeoutRunnable, + MULTI_TAP_TIMEOUT); + mMultiTapCount = 1; + mMultiTapKeyCode = keyEvent.getKeyCode(); + } + } else if (mMultiTapCount == 1) { + mHandler.removeCallbacks(mMultiTapTimeoutRunnable); + mMultiTapTimeoutRunnable = createDoubleTapRunnable(packageName, pid, uid, + asSystemService, keyEvent, needWakeLock, + isSingleTapOverridden(overriddenKeyEvents), + isDoubleTapOverridden(overriddenKeyEvents)); + if (isTripleTapOverridden(overriddenKeyEvents)) { + mHandler.postDelayed(mMultiTapTimeoutRunnable, MULTI_TAP_TIMEOUT); + mMultiTapCount = 2; + } else { + mMultiTapTimeoutRunnable.run(); + } + } else if (mMultiTapCount == 2) { + mHandler.removeCallbacks(mMultiTapTimeoutRunnable); + onTripleTap(keyEvent); + } + } else { + dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService, + keyEvent, needWakeLock); + } } } - private void cancelPendingIfNeeded(KeyEvent keyEvent) { - if (mPendingFirstDownKeyEvent == null) { + private boolean shouldTrackForMultipleTapsLocked(int overriddenKeyEvents) { + return isSingleTapOverridden(overriddenKeyEvents) + || isDoubleTapOverridden(overriddenKeyEvents) + || isTripleTapOverridden(overriddenKeyEvents); + } + + private void cancelTrackingIfNeeded(String packageName, int pid, int uid, + boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock, + int overriddenKeyEvents) { + if (mTrackingFirstDownKeyEvent == null && mMultiTapTimeoutRunnable == null) { return; } + if (isFirstDownKeyEvent(keyEvent)) { if (mLongPressTimeoutRunnable != null) { mHandler.removeCallbacks(mLongPressTimeoutRunnable); mLongPressTimeoutRunnable.run(); - } else { - resetLongPressTracking(); } + if (mMultiTapTimeoutRunnable != null && keyEvent.getKeyCode() != mMultiTapKeyCode) { + runExistingMultiTapRunnableLocked(); + } + resetLongPressTracking(); return; } - if (mPendingFirstDownKeyEvent.getDownTime() == keyEvent.getDownTime() - && mPendingFirstDownKeyEvent.getKeyCode() == keyEvent.getKeyCode() - && keyEvent.getAction() == KeyEvent.ACTION_DOWN - && keyEvent.getRepeatCount() > 1 && !mIsLongPressing) { - resetLongPressTracking(); + + if (mTrackingFirstDownKeyEvent != null + && mTrackingFirstDownKeyEvent.getDownTime() == keyEvent.getDownTime() + && mTrackingFirstDownKeyEvent.getKeyCode() == keyEvent.getKeyCode() + && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { + if (isFirstLongPressKeyEvent(keyEvent)) { + if (mMultiTapTimeoutRunnable != null) { + runExistingMultiTapRunnableLocked(); + } + if ((overriddenKeyEvents & KEY_EVENT_LONG_PRESS) == 0 + && !isVoiceKey(keyEvent.getKeyCode())) { + dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService, + mTrackingFirstDownKeyEvent, needWakeLock); + mTrackingFirstDownKeyEvent = null; + } + } else if (keyEvent.getRepeatCount() > 1 && !mIsLongPressing) { + resetLongPressTracking(); + } } } - private boolean needPending(KeyEvent keyEvent, int overriddenKeyEvents) { + private boolean needTracking(KeyEvent keyEvent, int overriddenKeyEvents) { if (!isFirstDownKeyEvent(keyEvent)) { - if (mPendingFirstDownKeyEvent == null) { + if (mTrackingFirstDownKeyEvent == null) { return false; - } else if (mPendingFirstDownKeyEvent.getDownTime() != keyEvent.getDownTime() - || mPendingFirstDownKeyEvent.getKeyCode() != keyEvent.getKeyCode()) { + } else if (mTrackingFirstDownKeyEvent.getDownTime() != keyEvent.getDownTime() + || mTrackingFirstDownKeyEvent.getKeyCode() != keyEvent.getKeyCode()) { return false; } } @@ -2193,10 +2264,21 @@ public class MediaSessionService extends SystemService implements Monitor { return true; } + private void runExistingMultiTapRunnableLocked() { + mHandler.removeCallbacks(mMultiTapTimeoutRunnable); + mMultiTapTimeoutRunnable.run(); + } + + private void resetMultiTapTrackingLocked() { + mMultiTapCount = 0; + mMultiTapTimeoutRunnable = null; + mMultiTapKeyCode = 0; + } + private void handleLongPressLocked(KeyEvent keyEvent, boolean needWakeLock, int overriddenKeyEvents) { if (mCustomMediaKeyDispatcher != null - && mCustomMediaKeyDispatcher.isLongPressOverridden(overriddenKeyEvents)) { + && isLongPressOverridden(overriddenKeyEvents)) { mCustomMediaKeyDispatcher.onLongPress(keyEvent); if (mLongPressTimeoutRunnable != null) { @@ -2230,7 +2312,7 @@ public class MediaSessionService extends SystemService implements Monitor { } private void resetLongPressTracking() { - mPendingFirstDownKeyEvent = null; + mTrackingFirstDownKeyEvent = null; mIsLongPressing = false; mLongPressTimeoutRunnable = null; } @@ -2259,6 +2341,50 @@ public class MediaSessionService extends SystemService implements Monitor { keyEvent, needWakeLock); } + Runnable createSingleTapRunnable(String packageName, int pid, int uid, + boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock, + boolean overridden) { + return new Runnable() { + @Override + public void run() { + resetMultiTapTrackingLocked(); + if (overridden) { + mCustomMediaKeyDispatcher.onSingleTap(keyEvent); + } else { + dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService, + keyEvent, needWakeLock); + } + } + }; + }; + + Runnable createDoubleTapRunnable(String packageName, int pid, int uid, + boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock, + boolean singleTapOverridden, boolean doubleTapOverridden) { + return new Runnable() { + @Override + public void run() { + resetMultiTapTrackingLocked(); + if (doubleTapOverridden) { + mCustomMediaKeyDispatcher.onDoubleTap(keyEvent); + } else if (singleTapOverridden) { + mCustomMediaKeyDispatcher.onSingleTap(keyEvent); + mCustomMediaKeyDispatcher.onSingleTap(keyEvent); + } else { + dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService, + keyEvent, needWakeLock); + dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService, + keyEvent, needWakeLock); + } + } + }; + }; + + private void onTripleTap(KeyEvent keyEvent) { + resetMultiTapTrackingLocked(); + mCustomMediaKeyDispatcher.onTripleTap(keyEvent); + } + private void dispatchMediaKeyEventLocked(String packageName, int pid, int uid, boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) { if (mCurrentFullUserRecord.getMediaButtonSessionLocked() diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index 41d7fff52a91..b585b49928cd 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -36,6 +36,7 @@ import android.media.IAudioRoutesObserver; import android.media.IAudioService; import android.media.MediaRoute2Info; import android.media.MediaRoute2ProviderInfo; +import android.media.MediaRoute2ProviderService; import android.media.RouteDiscoveryPreference; import android.media.RoutingSessionInfo; import android.os.Bundle; @@ -47,6 +48,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; import java.util.Objects; @@ -80,6 +82,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { RoutingSessionInfo mDefaultSessionInfo; final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo(); + private final Object mRequestLock = new Object(); + @GuardedBy("mRequestLock") + private volatile SessionCreationRequest mPendingSessionCreationRequest; + final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() { @Override public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) { @@ -135,10 +141,27 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { @Override public void requestCreateSession(long requestId, String packageName, String routeId, Bundle sessionHints) { + // Assume a router without MODIFY_AUDIO_ROUTING permission can't request with + // a route ID different from the default route ID. The service should've filtered. + if (TextUtils.equals(routeId, DEFAULT_ROUTE_ID)) { + mCallback.onSessionCreated(this, requestId, mDefaultSessionInfo); + return; + } + if (TextUtils.equals(routeId, mSelectedRouteId)) { + mCallback.onSessionCreated(this, requestId, mSessionInfos.get(0)); + return; + } + + synchronized (mRequestLock) { + // Handle the previous request as a failure if exists. + if (mPendingSessionCreationRequest != null) { + mCallback.onRequestFailed(this, mPendingSessionCreationRequest.mRequestId, + MediaRoute2ProviderService.REASON_UNKNOWN_ERROR); + } + mPendingSessionCreationRequest = new SessionCreationRequest(requestId, routeId); + } transferToRoute(requestId, SYSTEM_SESSION_ID, routeId); - mCallback.onSessionCreated(this, requestId, mSessionInfos.get(0)); - //TODO: We should call after the session info is changed. } @Override @@ -280,6 +303,24 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build(); + + if (mPendingSessionCreationRequest != null) { + SessionCreationRequest sessionCreationRequest; + synchronized (mRequestLock) { + sessionCreationRequest = mPendingSessionCreationRequest; + mPendingSessionCreationRequest = null; + } + if (sessionCreationRequest != null) { + if (TextUtils.equals(mSelectedRouteId, sessionCreationRequest.mRouteId)) { + mCallback.onSessionCreated(this, + sessionCreationRequest.mRequestId, newSessionInfo); + } else { + mCallback.onRequestFailed(this, sessionCreationRequest.mRequestId, + MediaRoute2ProviderService.REASON_UNKNOWN_ERROR); + } + } + } + if (Objects.equals(oldSessionInfo, newSessionInfo)) { return false; } else { @@ -310,6 +351,16 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { mCallback.onSessionUpdated(this, sessionInfo); } + private static class SessionCreationRequest { + final long mRequestId; + final String mRouteId; + + SessionCreationRequest(long requestId, String routeId) { + this.mRequestId = requestId; + this.mRouteId = routeId; + } + } + private class VolumeChangeReceiver extends BroadcastReceiver { // This will be called in the main thread. @Override diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java index 75ffe35674d1..3dac106418c5 100644 --- a/services/core/java/com/android/server/net/NetworkStatsFactory.java +++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java @@ -385,11 +385,10 @@ public class NetworkStatsFactory { // Migrate data usage over a VPN to the TUN network. for (VpnInfo info : vpnArray) { delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces); + // Filter out debug entries as that may lead to over counting. + delta.filterDebugEntries(); } - // Filter out debug entries as that may lead to over counting. - delta.filterDebugEntries(); - // Update mTunAnd464xlatAdjustedStats with migrated delta. mTunAnd464xlatAdjustedStats.combineAllValues(delta); mTunAnd464xlatAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime()); diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 44173c6e661f..1951fc071d3a 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -47,6 +47,7 @@ import static android.net.NetworkTemplate.buildTemplateMobileWildcard; import static android.net.NetworkTemplate.buildTemplateWifiWildcard; import static android.net.TrafficStats.KB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES; +import static android.net.TrafficStats.UNSUPPORTED; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED; import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED; @@ -1031,6 +1032,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public long getUidStats(int uid, int type) { + final int callingUid = Binder.getCallingUid(); + if (callingUid != android.os.Process.SYSTEM_UID && callingUid != uid) { + return UNSUPPORTED; + } return nativeGetUidStat(uid, type, checkBpfStatsEnable()); } diff --git a/services/core/java/com/android/server/notification/BubbleExtractor.java b/services/core/java/com/android/server/notification/BubbleExtractor.java index b1a09c1c0d37..d7d413c2ffb0 100644 --- a/services/core/java/com/android/server/notification/BubbleExtractor.java +++ b/services/core/java/com/android/server/notification/BubbleExtractor.java @@ -17,7 +17,7 @@ package com.android.server.notification; import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; -import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; +import static android.app.NotificationChannel.ALLOW_BUBBLE_OFF; import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; @@ -82,10 +82,7 @@ public class BubbleExtractor implements NotificationSignalExtractor { // the app is allowed but there's no channel to check record.setAllowBubble(true); } else if (bubblePreference == BUBBLE_PREFERENCE_ALL) { - // by default the channel is not allowed, only don't bubble if the user specified - boolean userLockedNoBubbles = !recordChannel.canBubble() - && (recordChannel.getUserLockedFields() & USER_LOCKED_ALLOW_BUBBLE) != 0; - record.setAllowBubble(!userLockedNoBubbles); + record.setAllowBubble(recordChannel.getAllowBubbles() != ALLOW_BUBBLE_OFF); } else if (bubblePreference == BUBBLE_PREFERENCE_SELECTED) { record.setAllowBubble(recordChannel.canBubble()); } diff --git a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java index 83ca69956033..2f60e426245d 100644 --- a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java +++ b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java @@ -47,7 +47,7 @@ public class NotificationChannelExtractor implements NotificationSignalExtractor NotificationChannel updatedChannel = mConfig.getConversationNotificationChannel( record.getSbn().getPackageName(), record.getSbn().getUid(), record.getChannel().getId(), - record.getSbn().getShortcutId(mContext), true, false); + record.getSbn().getShortcutId(), true, false); record.updateNotificationChannel(updatedChannel); return null; diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 6c3177fe253a..76acf57db408 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -512,7 +512,7 @@ public class NotificationManagerService extends SystemService { private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE; private NotificationHistoryManager mHistoryManager; - private SnoozeHelper mSnoozeHelper; + protected SnoozeHelper mSnoozeHelper; private GroupHelper mGroupHelper; private int mAutoGroupAtCount; private boolean mIsTelevision; @@ -2718,12 +2718,12 @@ public class NotificationManagerService extends SystemService { } return text == null ? null : String.valueOf(text); } - + protected void maybeRegisterMessageSent(NotificationRecord r) { Context appContext = r.getSbn().getPackageContext(getContext()); - Notification.Builder nb = + Notification.Builder nb = Notification.Builder.recoverBuilder(appContext, r.getNotification()); - if (nb.getStyle() instanceof Notification.MessagingStyle) { + if (nb.getStyle() instanceof Notification.MessagingStyle && r.getShortcutInfo() == null) { mPreferencesHelper.setMessageSent(r.getSbn().getPackageName(), r.getUid()); handleSavePolicyFile(); } @@ -5627,7 +5627,7 @@ public class NotificationManagerService extends SystemService { if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) { channelId = (new Notification.TvExtender(notification)).getChannelId(); } - String shortcutId = n.getShortcutId(getContext()); + String shortcutId = n.getShortcutId(); final NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel( pkg, notificationUid, channelId, shortcutId, true /* parent ok */, false /* includeDeleted */); @@ -7913,7 +7913,7 @@ public class NotificationManagerService extends SystemService { void snoozeNotificationInt(String key, long duration, String snoozeCriterionId, ManagedServiceInfo listener) { String listenerName = listener == null ? null : listener.component.toShortString(); - if (duration <= 0 && snoozeCriterionId == null || key == null) { + if ((duration <= 0 && snoozeCriterionId == null) || key == null) { return; } diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index e45b41df38b2..8e3de1598275 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -1386,10 +1386,6 @@ public final class NotificationRecord { || !Notification.MessagingStyle.class.equals(notification.getNotificationStyle())) { return false; } - if (mShortcutInfo == null && Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 1) { - return false; - } if (mIsNotConversationOverride) { return false; } diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java index e4a17740b0b7..da7864ba32c4 100644 --- a/services/core/java/com/android/server/notification/NotificationShellCmd.java +++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java @@ -50,6 +50,7 @@ import android.util.Slog; import java.io.PrintWriter; import java.net.URISyntaxException; import java.util.Collections; +import java.util.Date; /** * Implementation of `cmd notification` in NotificationManagerService. @@ -73,7 +74,12 @@ public class NotificationShellCmd extends ShellCommand { + " set_bubbles PACKAGE PREFERENCE (0=none 1=all 2=selected) " + "[user_id (current user if not specified)]\n" + " set_bubbles_channel PACKAGE CHANNEL_ID ALLOW " - + "[user_id (current user if not specified)]\n"; + + "[user_id (current user if not specified)]\n" + + " list\n" + + " get <notification-key>\n" + + " snooze --for <msec> <notification-key>\n" + + " unsnooze <notification-key>\n" + ; private static final String NOTIFY_USAGE = "usage: cmd notification post [flags] <tag> <text>\n\n" @@ -118,6 +124,10 @@ public class NotificationShellCmd extends ShellCommand { mPm = mDirectService.getContext().getPackageManager(); } + protected boolean checkShellCommandPermission(int callingUid) { + return (callingUid == Process.ROOT_UID || callingUid == Process.SHELL_UID); + } + @Override public int onCommand(String cmd) { if (cmd == null) { @@ -140,7 +150,17 @@ public class NotificationShellCmd extends ShellCommand { } finally { Binder.restoreCallingIdentity(identity); } + final PrintWriter pw = getOutPrintWriter(); + + if (!checkShellCommandPermission(callingUid)) { + Slog.e(TAG, "error: permission denied: callingUid=" + + callingUid + " callingPackage=" + callingPackage); + pw.println("error: permission denied: callingUid=" + + callingUid + " callingPackage=" + callingPackage); + return 255; + } + try { switch (cmd.replace('-', '_')) { case "set_dnd": { @@ -316,6 +336,100 @@ public class NotificationShellCmd extends ShellCommand { case "notify": doNotify(pw, callingPackage, callingUid); break; + case "list": + for (String key : mDirectService.mNotificationsByKey.keySet()) { + pw.println(key); + } + break; + case "get": { + final String key = getNextArgRequired(); + final NotificationRecord nr = mDirectService.getNotificationRecord(key); + if (nr != null) { + nr.dump(pw, "", mDirectService.getContext(), false); + } else { + pw.println("error: no active notification matching key: " + key); + return 1; + } + break; + } + case "snoozed": { + final StringBuilder sb = new StringBuilder(); + final SnoozeHelper sh = mDirectService.mSnoozeHelper; + for (NotificationRecord nr : sh.getSnoozed()) { + final String pkg = nr.getSbn().getPackageName(); + final String key = nr.getKey(); + pw.println(key + " snoozed, time=" + + sh.getSnoozeTimeForUnpostedNotification( + nr.getUserId(), pkg, key) + + " context=" + + sh.getSnoozeContextForUnpostedNotification( + nr.getUserId(), pkg, key)); + } + break; + } + case "unsnooze": { + boolean mute = false; + String key = getNextArgRequired(); + if ("--mute".equals(key)) { + mute = true; + key = getNextArgRequired(); + } + if (null != mDirectService.mSnoozeHelper.getNotification(key)) { + pw.println("unsnoozing: " + key); + mDirectService.unsnoozeNotificationInt(key, null, mute); + } else { + pw.println("error: no snoozed otification matching key: " + key); + return 1; + } + break; + } + case "snooze": { + String subflag = getNextArg(); + if (subflag == null) { + subflag = "help"; + } else if (subflag.startsWith("--")) { + subflag = subflag.substring(2); + } + String flagarg = getNextArg(); + String key = getNextArg(); + if (key == null) subflag = "help"; + String criterion = null; + long duration = 0; + switch (subflag) { + case "context": + case "condition": + case "criterion": + criterion = flagarg; + break; + case "until": + case "for": + case "duration": + duration = Long.parseLong(flagarg); + break; + default: + pw.println("usage: cmd notification snooze (--for <msec> | " + + "--context <snooze-criterion-id>) <key>"); + return 1; + } + if (null == mDirectService.getNotificationRecord(key)) { + pw.println("error: no notification matching key: " + key); + return 1; + } + if (duration > 0 || criterion != null) { + if (duration > 0) { + pw.println(String.format("snoozing <%s> until time: %s", key, + new Date(System.currentTimeMillis() + duration))); + } else { + pw.println(String.format("snoozing <%s> until criterion: %s", key, + criterion)); + } + mDirectService.snoozeNotificationInt(key, duration, criterion, null); + } else { + pw.println("error: invalid value for --" + subflag + ": " + flagarg); + return 1; + } + break; + } default: return handleDefaultCommands(cmd); } diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 6d7b410b0b99..a4b99b376b30 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -116,7 +116,7 @@ public class PreferencesHelper implements RankingConfig { private static final String ATT_ENABLED = "enabled"; private static final String ATT_USER_ALLOWED = "allowed"; private static final String ATT_HIDE_SILENT = "hide_gentle"; - private static final String ATT_SENT_MESSAGE = "sent_msg"; + private static final String ATT_SENT_MESSAGE = "sent_invalid_msg"; private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT; private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE; @@ -194,8 +194,6 @@ public class PreferencesHelper implements RankingConfig { updateBadgingEnabled(); updateBubblesEnabled(); syncChannelsBypassingDnd(mContext.getUserId()); - mAllowInvalidShortcuts = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 0; } public void readXml(XmlPullParser parser, boolean forRestore, int userId) @@ -1313,7 +1311,9 @@ public class PreferencesHelper implements RankingConfig { int N = r.channels.size(); for (int i = 0; i < N; i++) { final NotificationChannel nc = r.channels.valueAt(i); - if (!TextUtils.isEmpty(nc.getConversationId()) && !nc.isDeleted()) { + if (!TextUtils.isEmpty(nc.getConversationId()) + && !nc.isDeleted() + && !nc.isDemoted()) { ConversationChannelWrapper conversation = new ConversationChannelWrapper(); conversation.setPkg(r.pkg); conversation.setUid(r.uid); diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java index 13892ba0e480..e79d33fa5f7a 100644 --- a/services/core/java/com/android/server/notification/ShortcutHelper.java +++ b/services/core/java/com/android/server/notification/ShortcutHelper.java @@ -18,7 +18,7 @@ package com.android.server.notification; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC; -import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED; +import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER; import android.annotation.NonNull; import android.content.IntentFilter; @@ -152,9 +152,13 @@ public class ShortcutHelper { if (shortcutInfo == null || !shortcutInfo.isLongLived() || !shortcutInfo.isEnabled()) { return false; } - return mShortcutServiceInternal.isSharingShortcut(callingUserId, "android", + // TODO (b/155016294) uncomment when sharing shortcuts are required + /* + mShortcutServiceInternal.isSharingShortcut(callingUserId, "android", shortcutInfo.getPackage(), shortcutInfo.getId(), shortcutInfo.getUserId(), SHARING_FILTER); + */ + return true; } /** @@ -172,7 +176,8 @@ public class ShortcutHelper { LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery(); query.setPackage(packageName); query.setShortcutIds(Arrays.asList(shortcutId)); - query.setQueryFlags(FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_CACHED); + query.setQueryFlags( + FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED_BY_ANY_LAUNCHER | FLAG_MATCH_CACHED); List<ShortcutInfo> shortcuts = mLauncherAppsService.getShortcuts(query, user); ShortcutInfo info = shortcuts != null && shortcuts.size() > 0 ? shortcuts.get(0) diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java index 7df8fc7e34ed..910ed44df0f8 100644 --- a/services/core/java/com/android/server/om/IdmapDaemon.java +++ b/services/core/java/com/android/server/om/IdmapDaemon.java @@ -44,7 +44,7 @@ class IdmapDaemon { // The amount of time in milliseconds to wait when attempting to connect to idmap service. private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000; - private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 200; + private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 5; private static final String IDMAP_DAEMON = "idmap2d"; diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java index 91979564fe96..ef6655dd224e 100644 --- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java +++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java @@ -23,7 +23,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.net.Uri; import android.os.Process; -import android.os.RemoteException; import android.text.TextUtils; import android.util.Pair; @@ -140,7 +139,7 @@ public class OverlayActorEnforcer { return ActorState.MISSING_LEGACY_PERMISSION; } } - } catch (RemoteException | IOException e) { + } catch (IOException e) { return ActorState.ERROR_READING_OVERLAYABLE; } } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index c81f7cd4a8b4..6a8e465529d7 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -1120,7 +1120,11 @@ public final class OverlayManagerService extends SystemService { @Override public List<PackageInfo> getOverlayPackages(final int userId) { - return mPackageManagerInternal.getOverlayPackages(userId); + final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId); + for (final PackageInfo info : overlays) { + cachePackageInfo(info.packageName, userId, info); + } + return overlays; } @Nullable @@ -1151,9 +1155,8 @@ public final class OverlayManagerService extends SystemService { @Override public boolean doesTargetDefineOverlayable(String targetPackageName, int userId) - throws RemoteException, IOException { - PackageInfo packageInfo = mPackageManager.getPackageInfo(targetPackageName, 0, - userId); + throws IOException { + PackageInfo packageInfo = getPackageInfo(targetPackageName, userId); if (packageInfo == null) { throw new IOException("Unable to get target package"); } diff --git a/services/core/java/com/android/server/om/OverlayableInfoCallback.java b/services/core/java/com/android/server/om/OverlayableInfoCallback.java index 6b818849c257..5066ecdd6316 100644 --- a/services/core/java/com/android/server/om/OverlayableInfoCallback.java +++ b/services/core/java/com/android/server/om/OverlayableInfoCallback.java @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.content.om.OverlayableInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.os.RemoteException; import com.android.server.pm.PackageManagerServiceUtils; @@ -68,8 +67,7 @@ public interface OverlayableInfoCallback { /** * @return true if the target package has declared an overlayable */ - boolean doesTargetDefineOverlayable(String targetPackageName, int userId) - throws RemoteException, IOException; + boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException; /** * @throws SecurityException containing message if the caller doesn't have the given diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 1c41c2eb4702..4872b66ff1b4 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -60,7 +60,6 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; @@ -290,6 +289,21 @@ public abstract class ApexManager { abstract void registerApkInApex(AndroidPackage pkg); /** + * Reports error raised during installation of apk-in-apex. + * + * @param scanDir the directory of the apex inside which apk-in-apex resides. + */ + abstract void reportErrorWithApkInApex(String scanDirPath); + + /** + * Returns true if there were no errors when installing apk-in-apex inside + * {@param apexPackageName}, otherwise false. + * + * @param apexPackageName Package name of the apk container of apex + */ + abstract boolean isApkInApexInstallSuccess(String apexPackageName); + + /** * Returns list of {@code packageName} of apks inside the given apex. * @param apexPackageName Package name of the apk container of apex */ @@ -368,6 +382,13 @@ public abstract class ApexManager { @GuardedBy("mLock") private ArrayMap<String, List<String>> mApksInApex = new ArrayMap<>(); + /** + * Contains the list of {@code Exception}s that were raised when installing apk-in-apex + * inside {@code apexModuleName}. + */ + @GuardedBy("mLock") + private Set<String> mErrorWithApkInApex = new ArraySet<>(); + @GuardedBy("mLock") private List<PackageInfo> mAllPackagesCache; @@ -733,9 +754,7 @@ public abstract class ApexManager { @Override void registerApkInApex(AndroidPackage pkg) { synchronized (mLock) { - final Iterator<ActiveApexInfo> it = mActiveApexInfosCache.iterator(); - while (it.hasNext()) { - final ActiveApexInfo aai = it.next(); + for (ActiveApexInfo aai : mActiveApexInfosCache) { if (pkg.getBaseCodePath().startsWith(aai.apexDirectory.getAbsolutePath())) { List<String> apks = mApksInApex.get(aai.apexModuleName); if (apks == null) { @@ -749,6 +768,30 @@ public abstract class ApexManager { } @Override + void reportErrorWithApkInApex(String scanDirPath) { + synchronized (mLock) { + for (ActiveApexInfo aai : mActiveApexInfosCache) { + if (scanDirPath.startsWith(aai.apexDirectory.getAbsolutePath())) { + mErrorWithApkInApex.add(aai.apexModuleName); + } + } + } + } + + @Override + boolean isApkInApexInstallSuccess(String apexPackageName) { + synchronized (mLock) { + Preconditions.checkState(mPackageNameToApexModuleName != null, + "APEX packages have not been scanned"); + String moduleName = mPackageNameToApexModuleName.get(apexPackageName); + if (moduleName == null) { + return false; + } + return !mErrorWithApkInApex.contains(moduleName); + } + } + + @Override List<String> getApksInApex(String apexPackageName) { synchronized (mLock) { Preconditions.checkState(mPackageNameToApexModuleName != null, @@ -1040,6 +1083,16 @@ public abstract class ApexManager { } @Override + void reportErrorWithApkInApex(String scanDirPath) { + // No-op + } + + @Override + boolean isApkInApexInstallSuccess(String apexPackageName) { + return true; + } + + @Override List<String> getApksInApex(String apexPackageName) { return Collections.emptyList(); } diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java index f1e14331e33f..3f6b8e92ef74 100644 --- a/services/core/java/com/android/server/pm/ComponentResolver.java +++ b/services/core/java/com/android/server/pm/ComponentResolver.java @@ -33,7 +33,6 @@ import android.content.pm.AuxiliaryResolveInfo; import android.content.pm.InstantAppResolveInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; -import android.content.pm.PackageManagerInternal.PrivateResolveFlags; import android.content.pm.PackageUserState; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; @@ -261,10 +260,9 @@ public class ComponentResolver { @Nullable List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags, - @PrivateResolveFlags int privateResolveFlags, int userId) { + int userId) { synchronized (mLock) { - return mActivities.queryIntent( - intent, resolvedType, flags, privateResolveFlags, userId); + return mActivities.queryIntent(intent, resolvedType, flags, userId); } } @@ -427,7 +425,7 @@ public class ComponentResolver { @Nullable List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags, int userId) { synchronized (mLock) { - return mReceivers.queryIntent(intent, resolvedType, flags, 0, userId); + return mReceivers.queryIntent(intent, resolvedType, flags, userId); } } @@ -1293,12 +1291,11 @@ public class ComponentResolver { } List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, - int privateResolveFlags, int userId) { + int userId) { if (!sUserManager.exists(userId)) { return null; } mFlags = flags; - mPrivateResolveFlags = privateResolveFlags; return super.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); @@ -1495,11 +1492,6 @@ public class ComponentResolver { } return null; } - final boolean matchNonBrowserOnly = - (mPrivateResolveFlags & PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY) != 0; - if (matchNonBrowserOnly && info.handleAllWebDataURI()) { - return null; - } final ResolveInfo res = new ResolveInfo(); res.activityInfo = ai; if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { @@ -1579,7 +1571,6 @@ public class ComponentResolver { private final ArrayMap<ComponentName, ParsedActivity> mActivities = new ArrayMap<>(); private int mFlags; - private int mPrivateResolveFlags; } // Both receivers and activities share a class, but point to different get methods diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 1d5c30438870..385ace8a511b 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -746,9 +746,8 @@ public class LauncherAppsService extends SystemService { } UserHandle user = UserHandle.of(injectCallingUserId()); - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) - == PackageManager.PERMISSION_GRANTED) { + if (injectHasInteractAcrossUsersFullPermission(injectBinderCallingPid(), + injectBinderCallingUid())) { user = null; } @@ -1053,29 +1052,6 @@ public class LauncherAppsService extends SystemService { } public static class ShortcutChangeHandler implements LauncherApps.ShortcutChangeCallback { - - static class QueryInfo { - final long mChangedSince; - final String mPackage; - final List<String> mShortcutIds; - final List<LocusId> mLocusIds; - final ComponentName mActivity; - final int mQueryFlags; - final UserHandle mCallbackUser; - - QueryInfo(long changedSince, String packageName, List<String> shortcutIds, - List<LocusId> locusIds, ComponentName activity, int flags, - UserHandle callbackUser) { - mChangedSince = changedSince; - mPackage = packageName; - mShortcutIds = shortcutIds; - mLocusIds = locusIds; - mActivity = activity; - mQueryFlags = flags; - mCallbackUser = callbackUser; - } - } - private final UserManagerInternal mUserManagerInternal; ShortcutChangeHandler(UserManagerInternal userManager) { @@ -1088,9 +1064,7 @@ public class LauncherAppsService extends SystemService { public synchronized void addShortcutChangeCallback(IShortcutChangeCallback callback, ShortcutQueryWrapper query, UserHandle user) { mCallbacks.unregister(callback); - mCallbacks.register(callback, new QueryInfo(query.getChangedSince(), - query.getPackage(), query.getShortcutIds(), query.getLocusIds(), - query.getActivity(), query.getQueryFlags(), user)); + mCallbacks.register(callback, new Pair<>(query, user)); } public synchronized void removeShortcutChangeCallback( @@ -1116,16 +1090,19 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < count; i++) { final IShortcutChangeCallback callback = mCallbacks.getBroadcastItem(i); - final QueryInfo query = (QueryInfo) mCallbacks.getBroadcastCookie(i); + final Pair<ShortcutQueryWrapper, UserHandle> cookie = + (Pair<ShortcutQueryWrapper, UserHandle>) + mCallbacks.getBroadcastCookie(i); - if (query.mCallbackUser != null && !hasUserAccess(query.mCallbackUser, user)) { + final UserHandle callbackUser = cookie.second; + if (callbackUser != null && !hasUserAccess(callbackUser, user)) { // Callback owner does not have access to the shortcuts' user. continue; } // Filter the list by query, if any matches exists, send via callback. - List<ShortcutInfo> matchedList = - filterShortcutsByQuery(packageName, shortcuts, query); + List<ShortcutInfo> matchedList = filterShortcutsByQuery(packageName, shortcuts, + cookie.first, shortcutsRemoved); if (!CollectionUtils.isEmpty(matchedList)) { try { if (shortcutsRemoved) { @@ -1143,21 +1120,25 @@ public class LauncherAppsService extends SystemService { } public static List<ShortcutInfo> filterShortcutsByQuery(String packageName, - List<ShortcutInfo> shortcuts, QueryInfo query) { - if (query.mPackage != null && query.mPackage != packageName) { + List<ShortcutInfo> shortcuts, ShortcutQueryWrapper query, + boolean shortcutsRemoved) { + final long changedSince = query.getChangedSince(); + final String queryPackage = query.getPackage(); + final List<String> shortcutIds = query.getShortcutIds(); + final List<LocusId> locusIds = query.getLocusIds(); + final ComponentName activity = query.getActivity(); + final int flags = query.getQueryFlags(); + + if (queryPackage != null && !queryPackage.equals(packageName)) { return null; } List<ShortcutInfo> matches = new ArrayList<>(); - final boolean matchDynamic = - (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0; - final boolean matchPinned = - (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0; - final boolean matchManifest = - (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0; - final boolean matchCached = - (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_CACHED) != 0; + final boolean matchDynamic = (flags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0; + final boolean matchPinned = (flags & ShortcutQuery.FLAG_MATCH_PINNED) != 0; + final boolean matchManifest = (flags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0; + final boolean matchCached = (flags & ShortcutQuery.FLAG_MATCH_CACHED) != 0; final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0) | (matchPinned ? ShortcutInfo.FLAG_PINNED : 0) | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0) @@ -1166,24 +1147,19 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < shortcuts.size(); i++) { final ShortcutInfo si = shortcuts.get(i); - if (query.mActivity != null && !query.mActivity.equals(si.getActivity())) { + if (activity != null && !activity.equals(si.getActivity())) { continue; } - - if (query.mChangedSince != 0 - && query.mChangedSince > si.getLastChangedTimestamp()) { + if (changedSince != 0 && changedSince > si.getLastChangedTimestamp()) { continue; } - - if (query.mShortcutIds != null && !query.mShortcutIds.contains(si.getId())) { + if (shortcutIds != null && !shortcutIds.contains(si.getId())) { continue; } - - if (query.mLocusIds != null && !query.mLocusIds.contains(si.getLocusId())) { + if (locusIds != null && !locusIds.contains(si.getLocusId())) { continue; } - - if ((shortcutFlags & si.getFlags()) != 0) { + if (shortcutsRemoved || (shortcutFlags & si.getFlags()) != 0) { matches.add(si); } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 8e7eaf6e29fa..9c0ac1884bd5 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -163,6 +163,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final int MSG_STREAM_VALIDATE_AND_COMMIT = 1; private static final int MSG_INSTALL = 2; private static final int MSG_ON_PACKAGE_INSTALLED = 3; + private static final int MSG_SESSION_VERIFICATION_FAILURE = 4; /** XML constants used for persisting a session */ static final String TAG_SESSION = "session"; @@ -449,6 +450,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { packageName, returnCode, message, extras); break; + case MSG_SESSION_VERIFICATION_FAILURE: + final int error = msg.arg1; + final String detailMessage = (String) msg.obj; + onSessionVerificationFailure(error, detailMessage); + break; } return true; @@ -1479,15 +1485,22 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } private PackageManagerException onSessionVerificationFailure(PackageManagerException e) { + onSessionVerificationFailure(e.error, ExceptionUtils.getCompleteMessage(e)); + return e; + } + + private void onSessionVerificationFailure(int error, String detailMessage) { // Session is sealed but could not be verified, we need to destroy it. destroyInternal(); // Dispatch message to remove session from PackageInstallerService. - dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null); - - return e; + dispatchSessionFinished(error, detailMessage, null); } private void onDataLoaderUnrecoverable() { + if (TextUtils.isEmpty(mPackageName)) { + // The package has not been installed. + return; + } final PackageManagerService packageManagerService = mPm; final String packageName = mPackageName; mHandler.post(() -> { @@ -2610,12 +2623,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { case IDataLoaderStatusListener.DATA_LOADER_STOPPED: case IDataLoaderStatusListener.DATA_LOADER_DESTROYED: return; - case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE: - onDataLoaderUnrecoverable(); - return; } if (mDestroyed || mDataLoaderFinished) { + switch (status) { + case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE: + onDataLoaderUnrecoverable(); + return; + } return; } @@ -2623,9 +2638,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { IDataLoader dataLoader = dataLoaderManager.getDataLoader(dataLoaderId); if (dataLoader == null) { mDataLoaderFinished = true; - onSessionVerificationFailure( - new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, - "Failure to obtain data loader")); + dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE, + "Failure to obtain data loader"); return; } @@ -2670,20 +2684,30 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } case IDataLoaderStatusListener.DATA_LOADER_IMAGE_NOT_READY: { mDataLoaderFinished = true; - onSessionVerificationFailure( - new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, - "Failed to prepare image.")); + dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE, + "Failed to prepare image."); if (manualStartAndDestroy) { dataLoader.destroy(dataLoaderId); } break; } + case IDataLoaderStatusListener.DATA_LOADER_UNAVAILABLE: { + // Don't fail or commit the session. Allow caller to commit again. + sendPendingStreaming(mContext, mRemoteStatusReceiver, sessionId, + "DataLoader unavailable"); + break; + } + case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE: + mDataLoaderFinished = true; + dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE, + "DataLoader reported unrecoverable failure."); + break; } } catch (RemoteException e) { // In case of streaming failure we don't want to fail or commit the session. // Just return from this method and allow caller to commit again. sendPendingStreaming(mContext, mRemoteStatusReceiver, sessionId, - new StreamingException(e)); + e.getMessage()); } } }; @@ -2708,6 +2732,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return false; } + private void dispatchSessionVerificationFailure(int error, String detailMessage) { + mHandler.obtainMessage(MSG_SESSION_VERIFICATION_FAILURE, error, -1, + detailMessage).sendToTarget(); + } + @Override public int[] getChildSessionIds() { final int[] childSessionIds = mChildSessionIds.copyKeys(); @@ -3036,13 +3065,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } private static void sendPendingStreaming(Context context, IntentSender target, int sessionId, - Throwable cause) { + @Nullable String cause) { final Intent intent = new Intent(); intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_STREAMING); - if (cause != null && !TextUtils.isEmpty(cause.getMessage())) { + if (!TextUtils.isEmpty(cause)) { intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, - "Staging Image Not Ready [" + cause.getMessage() + "]"); + "Staging Image Not Ready [" + cause + "]"); } else { intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready"); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8b191dda5590..a4d74f0d7fc3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4420,6 +4420,11 @@ public class PackageManagerService extends IPackageManager.Stub if (getInstantAppPackageName(callingUid) != null) { throw new SecurityException("Instant applications don't have access to this method"); } + if (!mUserManager.exists(userId)) { + throw new SecurityException("User doesn't exist"); + } + mPermissionManager.enforceCrossUserPermission( + callingUid, userId, false, false, "checkPackageStartable"); final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(packageName); @@ -4944,6 +4949,21 @@ public class PackageManagerService extends IPackageManager.Stub } return ai; } + if ((flags & PackageManager.MATCH_APEX) != 0) { + // For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo + // returned from getApplicationInfo, but for APEX packages difference shouldn't be + // very big. + // TODO(b/155328545): generate proper application info for APEXes as well. + int apexFlags = ApexManager.MATCH_ACTIVE_PACKAGE; + if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) { + apexFlags = ApexManager.MATCH_FACTORY_PACKAGE; + } + final PackageInfo pi = mApexManager.getPackageInfo(packageName, apexFlags); + if (pi == null) { + return null; + } + return pi.applicationInfo; + } if ("android".equals(packageName)||"system".equals(packageName)) { return mAndroidApplication; } @@ -5777,9 +5797,15 @@ public class PackageManagerService extends IPackageManager.Stub @Override public ChangedPackages getChangedPackages(int sequenceNumber, int userId) { - if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + final int callingUid = Binder.getCallingUid(); + if (getInstantAppPackageName(callingUid) != null) { return null; } + if (!mUserManager.exists(userId)) { + return null; + } + mPermissionManager.enforceCrossUserPermission( + callingUid, userId, false, false, "getChangedPackages"); synchronized (mLock) { if (sequenceNumber >= mChangedPackagesSequenceNumber) { return null; @@ -6388,6 +6414,11 @@ public class PackageManagerService extends IPackageManager.Stub final ResolveInfo bestChoice = chooseBestActivity( intent, resolvedType, flags, privateResolveFlags, query, userId); + final boolean nonBrowserOnly = + (privateResolveFlags & PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY) != 0; + if (nonBrowserOnly && bestChoice != null && bestChoice.handleAllWebDataURI) { + return null; + } return bestChoice; } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); @@ -6575,9 +6606,13 @@ public class PackageManagerService extends IPackageManager.Stub if (ri != null) { return ri; } - // If we have an ephemeral app, use it + int browserCount = 0; for (int i = 0; i < N; i++) { ri = query.get(i); + if (ri.handleAllWebDataURI) { + browserCount++; + } + // If we have an ephemeral app, use it if (ri.activityInfo.applicationInfo.isInstantApp()) { final String packageName = ri.activityInfo.packageName; final PackageSetting ps = mSettings.mPackages.get(packageName); @@ -6593,6 +6628,9 @@ public class PackageManagerService extends IPackageManager.Stub return null; } ri = new ResolveInfo(mResolveInfo); + // if all resolve options are browsers, mark the resolver's info as if it were + // also a browser. + ri.handleAllWebDataURI = browserCount == N; ri.activityInfo = new ActivityInfo(ri.activityInfo); ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); // If all of the options come from the same package, show the application's @@ -7103,7 +7141,7 @@ public class PackageManagerService extends IPackageManager.Stub // Check for results in the current profile. result = filterIfNotSystemUser(mComponentResolver.queryActivities( - intent, resolvedType, flags, privateResolveFlags, userId), userId); + intent, resolvedType, flags, userId), userId); addInstant = isInstantAppResolutionAllowed(intent, result, userId, false /*skipPackageCheck*/); // Check for cross profile results. @@ -7202,7 +7240,7 @@ public class PackageManagerService extends IPackageManager.Stub | PackageManager.GET_RESOLVED_FILTER | PackageManager.MATCH_INSTANT | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY, - 0, userId); + userId); for (int i = instantApps.size() - 1; i >= 0; --i) { final ResolveInfo info = instantApps.get(i); final String packageName = info.activityInfo.packageName; @@ -7306,7 +7344,7 @@ public class PackageManagerService extends IPackageManager.Stub return null; } List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent, - resolvedType, flags, 0, parentUserId); + resolvedType, flags, parentUserId); if (resultTargetUser == null || resultTargetUser.isEmpty()) { return null; @@ -7754,7 +7792,7 @@ public class PackageManagerService extends IPackageManager.Stub String resolvedType, int flags, int sourceUserId) { int targetUserId = filter.getTargetUserId(); List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent, - resolvedType, flags, 0, targetUserId); + resolvedType, flags, targetUserId); if (resultTargetUser != null && isUserEnabled(targetUserId)) { // If all the matches in the target profile are suspended, return null. for (int i = resultTargetUser.size() - 1; i >= 0; i--) { @@ -8772,8 +8810,10 @@ public class PackageManagerService extends IPackageManager.Stub private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) { if (!mUserManager.exists(userId)) return null; - flags = updateFlagsForComponent(flags, userId); final int callingUid = Binder.getCallingUid(); + mPermissionManager.enforceCrossUserPermission( + callingUid, userId, false, false, "resolveContentProvider"); + flags = updateFlagsForComponent(flags, userId); final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId); if (providerInfo == null) { return null; @@ -8972,6 +9012,10 @@ public class PackageManagerService extends IPackageManager.Stub + parseResult.scanFile, throwable); } + if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) { + mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath()); + } + // Delete invalid userdata apps if ((scanFlags & SCAN_AS_SYSTEM) == 0 && errorCode != PackageManager.INSTALL_SUCCEEDED) { @@ -9369,7 +9413,8 @@ public class PackageManagerService extends IPackageManager.Stub getSharedLibLatestVersionSetting(scanResult))), mSettings.mKeySetManagerService); appIdCreated = optimisticallyRegisterAppId(scanResult); - commitReconciledScanResultLocked(reconcileResult.get(pkgName)); + commitReconciledScanResultLocked( + reconcileResult.get(pkgName), mUserManager.getUserIds()); } catch (PackageManagerException e) { if (appIdCreated) { cleanUpAppIdCreation(scanResult); @@ -9390,8 +9435,13 @@ public class PackageManagerService extends IPackageManager.Stub // TODO:(b/135203078): Move to parsing private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) { // Derive the new package synthetic package name - parsedPackage.setPackageName(parsedPackage.getPackageName() + STATIC_SHARED_LIB_DELIMITER - + parsedPackage.getStaticSharedLibVersion()); + parsedPackage.setPackageName(toStaticSharedLibraryPackageName( + parsedPackage.getPackageName(), parsedPackage.getStaticSharedLibVersion())); + } + + private static String toStaticSharedLibraryPackageName( + String packageName, long libraryVersion) { + return packageName + STATIC_SHARED_LIB_DELIMITER + libraryVersion; } static String fixProcessName(String defProcessName, String processName) { @@ -10332,7 +10382,7 @@ public class PackageManagerService extends IPackageManager.Stub final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos( pkgSetting.pkg, availablePackages, mSharedLibraries, null); executeSharedLibrariesUpdateLPr(pkg, pkgSetting, changingLib, changingLibSetting, - sharedLibraryInfos); + sharedLibraryInfos, mUserManager.getUserIds()); } private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg, @@ -10369,7 +10419,7 @@ public class PackageManagerService extends IPackageManager.Stub private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting, - ArrayList<SharedLibraryInfo> usesLibraryInfos) { + ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers) { // If the package provides libraries, clear their old dependencies. // This method will set them up again. applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> { @@ -10385,6 +10435,30 @@ public class PackageManagerService extends IPackageManager.Stub changingLibSetting); } pkgSetting.getPkgState().setUsesLibraryFiles(new ArrayList<>(usesLibraryFiles)); + // let's make sure we mark all static shared libraries as installed for the same users + // that its dependent packages are installed for. + int[] installedUsers = new int[allUsers.length]; + int installedUserCount = 0; + for (int u = 0; u < allUsers.length; u++) { + if (pkgSetting.getInstalled(allUsers[u])) { + installedUsers[installedUserCount++] = allUsers[u]; + } + } + for (SharedLibraryInfo sharedLibraryInfo : usesLibraryInfos) { + if (!sharedLibraryInfo.isStatic()) { + continue; + } + final PackageSetting staticLibPkgSetting = getPackageSetting( + toStaticSharedLibraryPackageName(sharedLibraryInfo.getPackageName(), + sharedLibraryInfo.getLongVersion())); + if (staticLibPkgSetting == null) { + Slog.wtf(TAG, "Shared lib without setting: " + sharedLibraryInfo); + continue; + } + for (int u = 0; u < installedUserCount; u++) { + staticLibPkgSetting.setInstalled(true, installedUsers[u]); + } + } } else { pkgSetting.getPkgState().setUsesLibraryInfos(Collections.emptyList()) .setUsesLibraryFiles(Collections.emptyList()); @@ -10878,7 +10952,7 @@ public class PackageManagerService extends IPackageManager.Stub */ @GuardedBy({"mLock", "mInstallLock"}) private AndroidPackage commitReconciledScanResultLocked( - @NonNull ReconciledPackage reconciledPkg) { + @NonNull ReconciledPackage reconciledPkg, int[] allUsers) { final ScanResult result = reconciledPkg.scanResult; final ScanRequest request = result.request; // TODO(b/135203078): Move this even further away @@ -10937,7 +11011,7 @@ public class PackageManagerService extends IPackageManager.Stub if (reconciledPkg.collectedSharedLibraryInfos != null) { executeSharedLibrariesUpdateLPr(pkg, pkgSetting, null, null, - reconciledPkg.collectedSharedLibraryInfos); + reconciledPkg.collectedSharedLibraryInfos, allUsers); } final KeySetManagerService ksms = mSettings.mKeySetManagerService; @@ -16482,7 +16556,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg); + AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg, request.mAllUsers); updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res); final PackageSetting ps = mSettings.mPackages.get(packageName); @@ -17122,7 +17196,12 @@ public class PackageManagerService extends IPackageManager.Stub // "updating same package" could also involve key-rotation. final boolean sigsOk; final String sourcePackageName = bp.getSourcePackageName(); - final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting(); + final PackageSetting sourcePackageSetting; + synchronized (mLock) { + sourcePackageSetting = mSettings.getPackageLPr(sourcePackageName); + } + final SigningDetails sourceSigningDetails = (sourcePackageSetting == null + ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails()); final KeySetManagerService ksms = mSettings.mKeySetManagerService; if (sourcePackageName.equals(parsedPackage.getPackageName()) && (ksms.shouldCheckUpgradeKeySetLocked( @@ -17133,18 +17212,19 @@ public class PackageManagerService extends IPackageManager.Stub // in the event of signing certificate rotation, we need to see if the // package's certificate has rotated from the current one, or if it is an // older certificate with which the current is ok with sharing permissions - if (sourcePackageSetting.signatures.mSigningDetails.checkCapability( + if (sourceSigningDetails.checkCapability( parsedPackage.getSigningDetails(), PackageParser.SigningDetails.CertCapabilities.PERMISSION)) { sigsOk = true; } else if (parsedPackage.getSigningDetails().checkCapability( - sourcePackageSetting.signatures.mSigningDetails, + sourceSigningDetails, PackageParser.SigningDetails.CertCapabilities.PERMISSION)) { - // the scanned package checks out, has signing certificate rotation // history, and is newer; bring it over - sourcePackageSetting.signatures.mSigningDetails = - parsedPackage.getSigningDetails(); + synchronized (mLock) { + sourcePackageSetting.signatures.mSigningDetails = + parsedPackage.getSigningDetails(); + } sigsOk = true; } else { sigsOk = false; diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index 1fc0a38e1ed3..71a4bb431985 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -256,7 +256,7 @@ class ShortcutPackage extends ShortcutPackageItem { if (shortcut != null) { mShortcutUser.mService.removeIconLocked(shortcut); shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED - | ShortcutInfo.FLAG_MANIFEST); + | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED); } return shortcut; } @@ -281,8 +281,10 @@ class ShortcutPackage extends ShortcutPackageItem { * invisible. * * It checks the max number of dynamic shortcuts. + * + * @return True if it replaced an existing shortcut, False otherwise. */ - public void addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) { + public boolean addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) { Preconditions.checkArgument(newShortcut.isEnabled(), "add/setDynamicShortcuts() cannot publish disabled shortcuts"); @@ -291,38 +293,59 @@ class ShortcutPackage extends ShortcutPackageItem { final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); + final boolean replaced; + final boolean wasPinned; + final boolean wasCached; if (oldShortcut == null) { + replaced = false; wasPinned = false; + wasCached = false; } else { // It's an update case. // Make sure the target is updatable. (i.e. should be mutable.) oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false); + replaced = true; wasPinned = oldShortcut.isPinned(); + wasCached = oldShortcut.isCached(); } // If it was originally pinned, the new one should be pinned too. if (wasPinned) { newShortcut.addFlags(ShortcutInfo.FLAG_PINNED); } + if (wasCached) { + newShortcut.addFlags(ShortcutInfo.FLAG_CACHED); + } forceReplaceShortcutInner(newShortcut); + return replaced; } /** * Push a shortcut. If the max number of dynamic shortcuts is already reached, remove the * shortcut with the lowest rank before adding the new shortcut. + * + * Any shortcut that gets altered (removed or changed) as a result of this push operation will + * be included and returned in changedShortcuts. + * + * @return True if a shortcut had to be removed to complete this operation, False otherwise. */ - public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut) { + public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut, + @NonNull List<ShortcutInfo> changedShortcuts) { Preconditions.checkArgument(newShortcut.isEnabled(), "pushDynamicShortcuts() cannot publish disabled shortcuts"); newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC); + changedShortcuts.clear(); final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); boolean wasPinned = false; + boolean wasCached = false; + + boolean deleted = false; if (oldShortcut == null) { final ShortcutService service = mShortcutUser.mService; @@ -343,10 +366,11 @@ class ShortcutPackage extends ShortcutPackageItem { // All shortcuts are manifest shortcuts and cannot be removed. Slog.e(TAG, "Failed to remove manifest shortcut while pushing dynamic shortcut " + newShortcut.getId()); - return false; + return true; // poppedShortcuts is empty which indicates a failure. } - deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true); + changedShortcuts.add(shortcut); + deleted = deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true) != null; } } else { // It's an update case. @@ -354,15 +378,19 @@ class ShortcutPackage extends ShortcutPackageItem { oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false); wasPinned = oldShortcut.isPinned(); + wasCached = oldShortcut.isCached(); } - // If it was originally pinned, the new one should be pinned too. + // If it was originally pinned or cached, the new one should be pinned or cached too. if (wasPinned) { newShortcut.addFlags(ShortcutInfo.FLAG_PINNED); } + if (wasCached) { + newShortcut.addFlags(ShortcutInfo.FLAG_CACHED); + } forceReplaceShortcutInner(newShortcut); - return true; + return deleted; } /** @@ -371,8 +399,7 @@ class ShortcutPackage extends ShortcutPackageItem { * @return List of removed shortcuts. */ private List<ShortcutInfo> removeOrphans() { - ArrayList<String> removeList = null; // Lazily initialize. - List<ShortcutInfo> removedShortcuts = null; + List<ShortcutInfo> removeList = null; for (int i = mShortcuts.size() - 1; i >= 0; i--) { final ShortcutInfo si = mShortcuts.valueAt(i); @@ -381,18 +408,16 @@ class ShortcutPackage extends ShortcutPackageItem { if (removeList == null) { removeList = new ArrayList<>(); - removedShortcuts = new ArrayList<>(); } - removeList.add(si.getId()); - removedShortcuts.add(si); + removeList.add(si); } if (removeList != null) { for (int i = removeList.size() - 1; i >= 0; i--) { - forceDeleteShortcutInner(removeList.get(i)); + forceDeleteShortcutInner(removeList.get(i).getId()); } } - return removedShortcuts; + return removeList; } /** @@ -424,68 +449,69 @@ class ShortcutPackage extends ShortcutPackageItem { * Remove a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned or cached, it'll remain as a pinned or cached shortcut, and is still enabled. * - * @return true if it's removed, or false if it was not actually removed because it is either + * @return The deleted shortcut, or null if it was not actually removed because it is either * pinned or cached. */ - public boolean deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) { - final ShortcutInfo removed = deleteOrDisableWithId( + public ShortcutInfo deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) { + return deleteOrDisableWithId( shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible, ShortcutInfo.DISABLED_REASON_NOT_DISABLED); - return removed == null; } /** - * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut + * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned, it'll remain as a pinned shortcut, but will be disabled. * - * @return true if it's actually removed because it wasn't pinned, or false if it's still - * pinned. + * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if + * it's still pinned. */ - private boolean disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible, + private ShortcutInfo disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible, int disabledReason) { - final ShortcutInfo disabled = deleteOrDisableWithId( - shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, ignoreInvisible, - disabledReason); - return disabled == null; + return deleteOrDisableWithId(shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, + ignoreInvisible, disabledReason); } /** * Remove a long lived shortcut by ID. If the shortcut is pinned, it'll remain as a pinned * shortcut, and is still enabled. * - * @return true if it's actually removed because it wasn't pinned, or false if it's still - * pinned. + * @return The deleted shortcut, or null if it was not actually removed because it's pinned. */ - public boolean deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) { + public ShortcutInfo deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) { final ShortcutInfo shortcut = mShortcuts.get(shortcutId); if (shortcut != null) { shortcut.clearFlags(ShortcutInfo.FLAG_CACHED); } - final ShortcutInfo removed = deleteOrDisableWithId( + return deleteOrDisableWithId( shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible, ShortcutInfo.DISABLED_REASON_NOT_DISABLED); - return removed == null; } /** * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned, it'll remain as a pinned shortcut but will be disabled. + * + * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if + * it's still pinned. */ - public void disableWithId(@NonNull String shortcutId, String disabledMessage, + public ShortcutInfo disableWithId(@NonNull String shortcutId, String disabledMessage, int disabledMessageResId, boolean overrideImmutable, boolean ignoreInvisible, int disabledReason) { - final ShortcutInfo disabled = deleteOrDisableWithId(shortcutId, /* disable =*/ true, + final ShortcutInfo deleted = deleteOrDisableWithId(shortcutId, /* disable =*/ true, overrideImmutable, ignoreInvisible, disabledReason); + // If disabled id still exists, it is pinned and we need to update the disabled message. + final ShortcutInfo disabled = mShortcuts.get(shortcutId); if (disabled != null) { if (disabledMessage != null) { disabled.setDisabledMessage(disabledMessage); } else if (disabledMessageResId != 0) { disabled.setDisabledMessageResId(disabledMessageResId); - mShortcutUser.mService.fixUpShortcutResourceNamesAndValues(disabled); } } + + return deleted; } @Nullable @@ -521,10 +547,10 @@ class ShortcutPackage extends ShortcutPackageItem { oldShortcut.setActivity(null); } - return oldShortcut; + return null; } else { forceDeleteShortcutInner(shortcutId); - return null; + return oldShortcut; } } @@ -762,7 +788,7 @@ class ShortcutPackage extends ShortcutPackageItem { // Get the list of all dynamic shortcuts in this package. final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); - findAll(shortcuts, ShortcutInfo::isDynamicVisible, + findAll(shortcuts, ShortcutInfo::isNonManifestVisible, ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION); final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>(); @@ -807,7 +833,8 @@ class ShortcutPackage extends ShortcutPackageItem { // Get the list of all dynamic shortcuts in this package final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); - findAll(shortcuts, ShortcutInfo::isDynamicVisible, ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER); + findAll(shortcuts, ShortcutInfo::isNonManifestVisible, + ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER); int sharingShortcutCount = 0; for (int i = 0; i < shortcuts.size(); i++) { @@ -1004,7 +1031,7 @@ class ShortcutPackage extends ShortcutPackageItem { "%s is no longer main activity. Disabling shorcut %s.", getPackageName(), si.getId())); if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false, - ShortcutInfo.DISABLED_REASON_APP_CHANGED)) { + ShortcutInfo.DISABLED_REASON_APP_CHANGED) != null) { continue; // Actually removed. } // Still pinned, so fall-through and possibly update the resources. diff --git a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java index 6fd997db8be8..d4a02a9ceb2a 100644 --- a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java +++ b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java @@ -35,7 +35,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -513,10 +513,6 @@ class ShortcutRequestPinProcessor { launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId, /*forPinRequest=*/ true); - if (changedShortcuts == null) { - changedShortcuts = new ArrayList<>(1); - } - changedShortcuts.add(original); if (current == null) { if (DEBUG) { @@ -526,6 +522,8 @@ class ShortcutRequestPinProcessor { } ps.adjustRanks(); // Shouldn't be needed, but just in case. + + changedShortcuts = Collections.singletonList(ps.findShortcutById(shortcutId)); } mService.verifyStates(); diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 8d53d1554619..e4ae007dadee 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -1666,11 +1666,10 @@ public class ShortcutService extends IShortcutService.Stub { * - Write to file */ void packageShortcutsChanged(@NonNull String packageName, @UserIdInt int userId, - @Nullable List<ShortcutInfo> addedOrUpdatedShortcuts, - @Nullable List<ShortcutInfo> removedShortcuts) { + @Nullable final List<ShortcutInfo> changedShortcuts, + @Nullable final List<ShortcutInfo> removedShortcuts) { notifyListeners(packageName, userId); - notifyShortcutChangeCallbacks(packageName, userId, addedOrUpdatedShortcuts, - removedShortcuts); + notifyShortcutChangeCallbacks(packageName, userId, changedShortcuts, removedShortcuts); scheduleSaveUser(userId); } @@ -1699,8 +1698,11 @@ public class ShortcutService extends IShortcutService.Stub { } private void notifyShortcutChangeCallbacks(@NonNull String packageName, @UserIdInt int userId, - @Nullable List<ShortcutInfo> addedOrUpdatedShortcuts, - @Nullable List<ShortcutInfo> removedShortcuts) { + @Nullable final List<ShortcutInfo> changedShortcuts, + @Nullable final List<ShortcutInfo> removedShortcuts) { + final List<ShortcutInfo> changedList = removeNonKeyFields(changedShortcuts); + final List<ShortcutInfo> removedList = removeNonKeyFields(removedShortcuts); + final UserHandle user = UserHandle.of(userId); injectPostToHandler(() -> { try { @@ -1713,12 +1715,11 @@ public class ShortcutService extends IShortcutService.Stub { copy = new ArrayList<>(mShortcutChangeCallbacks); } for (int i = copy.size() - 1; i >= 0; i--) { - if (!CollectionUtils.isEmpty(addedOrUpdatedShortcuts)) { - copy.get(i).onShortcutsAddedOrUpdated(packageName, addedOrUpdatedShortcuts, - user); + if (!CollectionUtils.isEmpty(changedList)) { + copy.get(i).onShortcutsAddedOrUpdated(packageName, changedList, user); } - if (!CollectionUtils.isEmpty(removedShortcuts)) { - copy.get(i).onShortcutsRemoved(packageName, removedShortcuts, user); + if (!CollectionUtils.isEmpty(removedList)) { + copy.get(i).onShortcutsRemoved(packageName, removedList, user); } } } catch (Exception ignore) { @@ -1726,6 +1727,25 @@ public class ShortcutService extends IShortcutService.Stub { }); } + private List<ShortcutInfo> removeNonKeyFields(@Nullable List<ShortcutInfo> shortcutInfos) { + if (CollectionUtils.isEmpty(shortcutInfos)) { + return shortcutInfos; + } + + final int size = shortcutInfos.size(); + List<ShortcutInfo> keyFieldOnlyShortcuts = new ArrayList<>(size); + + for (int i = 0; i < size; i++) { + final ShortcutInfo si = shortcutInfos.get(i); + if (si.hasKeyFieldsOnly()) { + keyFieldOnlyShortcuts.add(si); + } else { + keyFieldOnlyShortcuts.add(si.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO)); + } + } + return keyFieldOnlyShortcuts; + } + /** * Clean up / validate an incoming shortcut. * - Make sure all mandatory fields are set. @@ -1820,6 +1840,7 @@ public class ShortcutService extends IShortcutService.Stub { final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); + List<ShortcutInfo> changedShortcuts = null; List<ShortcutInfo> removedShortcuts = null; synchronized (mLock) { @@ -1846,7 +1867,12 @@ public class ShortcutService extends IShortcutService.Stub { fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false); } - // First, remove all un-pinned; dynamic shortcuts + ArrayList<ShortcutInfo> cachedOrPinned = new ArrayList<>(); + ps.findAll(cachedOrPinned, (ShortcutInfo si) -> si.isVisibleToPublisher() + && si.isDynamic() && (si.isCached() || si.isPinned()), + ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO); + + // First, remove all un-pinned and non-cached; dynamic shortcuts removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true); // Then, add/update all. We need to make sure to take over "pinned" flag. @@ -1857,8 +1883,12 @@ public class ShortcutService extends IShortcutService.Stub { // Lastly, adjust the ranks. ps.adjustRanks(); + + changedShortcuts = prepareChangedShortcuts( + cachedOrPinned, newShortcuts, removedShortcuts, ps); } - packageShortcutsChanged(packageName, userId, newShortcuts, removedShortcuts); + + packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts); verifyStates(); @@ -1916,6 +1946,11 @@ public class ShortcutService extends IShortcutService.Stub { "ShortcutInfo.enabled cannot be changed with updateShortcuts()"); } + if (target.isLongLived() != source.isLongLived()) { + Slog.w(TAG, + "ShortcutInfo.longLived cannot be changed with updateShortcuts()"); + } + // When updating the rank, we need to insert between existing ranks, so set // this setRankChanged, and also copy the implicit rank fo adjustRanks(). if (source.hasRank()) { @@ -2026,8 +2061,8 @@ public class ShortcutService extends IShortcutService.Stub { verifyCaller(packageName, userId); verifyShortcutInfoPackage(packageName, shortcut); - final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( - injectBinderCallingPid(), injectBinderCallingUid()); + List<ShortcutInfo> changedShortcuts = new ArrayList<>(); + List<ShortcutInfo> removedShortcuts = null; synchronized (mLock) { throwIfUserLockedL(userId); @@ -2052,14 +2087,22 @@ public class ShortcutService extends IShortcutService.Stub { shortcut.setRankChanged(); // Push it. - if (!ps.pushDynamicShortcut(shortcut)) { - return; + boolean deleted = ps.pushDynamicShortcut(shortcut, changedShortcuts); + + if (deleted) { + if (changedShortcuts.isEmpty()) { + return; // Failed to push. + } + removedShortcuts = Collections.singletonList(changedShortcuts.get(0)); + changedShortcuts.clear(); } + changedShortcuts.add(shortcut); // Lastly, adjust the ranks. ps.adjustRanks(); } - packageShortcutsChanged(packageName, userId, Collections.singletonList(shortcut), null); + + packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts); verifyStates(); } @@ -2147,6 +2190,9 @@ public class ShortcutService extends IShortcutService.Stub { verifyCaller(packageName, userId); Objects.requireNonNull(shortcutIds, "shortcutIds must be provided"); + List<ShortcutInfo> changedShortcuts = null; + List<ShortcutInfo> removedShortcuts = null; + synchronized (mLock) { throwIfUserLockedL(userId); @@ -2163,17 +2209,30 @@ public class ShortcutService extends IShortcutService.Stub { if (!ps.isShortcutExistsAndVisibleToPublisher(id)) { continue; } - ps.disableWithId(id, + + final ShortcutInfo deleted = ps.disableWithId(id, disabledMessageString, disabledMessageResId, /* overrideImmutable=*/ false, /*ignoreInvisible=*/ true, ShortcutInfo.DISABLED_REASON_BY_APP); + + if (deleted == null) { + if (changedShortcuts == null) { + changedShortcuts = new ArrayList<>(1); + } + changedShortcuts.add(ps.findShortcutById(id)); + } else { + if (removedShortcuts == null) { + removedShortcuts = new ArrayList<>(1); + } + removedShortcuts.add(deleted); + } } // We may have removed dynamic shortcuts which may have left a gap, so adjust the ranks. ps.adjustRanks(); } - // TODO: Disabling dynamic shortcuts will removed them if not pinned. Cover all cases. - packageShortcutsChanged(packageName, userId, null, null); + + packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts); verifyStates(); } @@ -2200,13 +2259,10 @@ public class ShortcutService extends IShortcutService.Stub { } ps.enableWithId(id); - final ShortcutInfo si = ps.findShortcutById(id); - if (si != null) { - if (changedShortcuts == null) { - changedShortcuts = new ArrayList<>(1); - } - changedShortcuts.add(si); + if (changedShortcuts == null) { + changedShortcuts = new ArrayList<>(1); } + changedShortcuts.add(ps.findShortcutById(id)); } } @@ -2237,18 +2293,18 @@ public class ShortcutService extends IShortcutService.Stub { if (!ps.isShortcutExistsAndVisibleToPublisher(id)) { continue; } - final ShortcutInfo si = ps.findShortcutById(id); - final boolean removed = ps.deleteDynamicWithId(id, /*ignoreInvisible=*/ true); - if (removed) { - if (removedShortcuts == null) { - removedShortcuts = new ArrayList<>(1); - } - removedShortcuts.add(si); - } else { + + ShortcutInfo removed = ps.deleteDynamicWithId(id, /*ignoreInvisible=*/ true); + if (removed == null) { if (changedShortcuts == null) { changedShortcuts = new ArrayList<>(1); } - changedShortcuts.add(si); + changedShortcuts.add(ps.findShortcutById(id)); + } else { + if (removedShortcuts == null) { + removedShortcuts = new ArrayList<>(1); + } + removedShortcuts.add(removed); } } @@ -2264,7 +2320,7 @@ public class ShortcutService extends IShortcutService.Stub { public void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); - List<ShortcutInfo> changedShortcuts = null; + List<ShortcutInfo> changedShortcuts = new ArrayList<>(); List<ShortcutInfo> removedShortcuts = null; synchronized (mLock) { @@ -2272,10 +2328,16 @@ public class ShortcutService extends IShortcutService.Stub { final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); + // Dynamic shortcuts that are either cached or pinned will not get deleted. + ps.findAll(changedShortcuts, (ShortcutInfo si) -> si.isVisibleToPublisher() + && si.isDynamic() && (si.isCached() || si.isPinned()), + ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO); + removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true); + changedShortcuts = prepareChangedShortcuts( + changedShortcuts, null, removedShortcuts, ps); } - // TODO: Pinned and cached shortcuts are not removed, add those to changedShortcuts list packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts); verifyStates(); @@ -2300,22 +2362,21 @@ public class ShortcutService extends IShortcutService.Stub { for (int i = shortcutIds.size() - 1; i >= 0; i--) { final String id = Preconditions.checkStringNotEmpty((String) shortcutIds.get(i)); + if (!ps.isShortcutExistsAndVisibleToPublisher(id)) { + continue; + } - final ShortcutInfo si = ps.findShortcutById(id); - final boolean removed = ps.deleteLongLivedWithId(id, /*ignoreInvisible=*/ true); - - if (si != null) { - if (removed) { - if (removedShortcuts == null) { - removedShortcuts = new ArrayList<>(1); - } - removedShortcuts.add(si); - } else { - if (changedShortcuts == null) { - changedShortcuts = new ArrayList<>(1); - } - changedShortcuts.add(si); + ShortcutInfo removed = ps.deleteLongLivedWithId(id, /*ignoreInvisible=*/ true); + if (removed != null) { + if (removedShortcuts == null) { + removedShortcuts = new ArrayList<>(1); + } + removedShortcuts.add(removed); + } else { + if (changedShortcuts == null) { + changedShortcuts = new ArrayList<>(1); } + changedShortcuts.add(ps.findShortcutById(id)); } } @@ -2939,6 +3000,7 @@ public class ShortcutService extends IShortcutService.Stub { Objects.requireNonNull(shortcutIds, "shortcutIds"); List<ShortcutInfo> changedShortcuts = null; + List<ShortcutInfo> removedShortcuts = null; synchronized (mLock) { throwIfUserLockedL(userId); @@ -2948,24 +3010,31 @@ public class ShortcutService extends IShortcutService.Stub { getLauncherShortcutsLocked(callingPackage, userId, launcherUserId); launcher.attemptToRestoreIfNeededAndSave(); - launcher.pinShortcuts(userId, packageName, shortcutIds, /*forPinRequest=*/ false); - final ShortcutPackage sp = getUserShortcutsLocked(userId) .getPackageShortcutsIfExists(packageName); if (sp != null) { - for (int i = 0; i < shortcutIds.size(); i++) { - final ShortcutInfo si = sp.findShortcutById(shortcutIds.get(i)); - if (si != null) { - if (changedShortcuts == null) { - changedShortcuts = new ArrayList<>(1); - } - changedShortcuts.add(si); - } + // List the shortcuts that are pinned only, these will get removed. + removedShortcuts = new ArrayList<>(); + sp.findAll(removedShortcuts, (ShortcutInfo si) -> si.isVisibleToPublisher() + && si.isPinned() && !si.isCached() && !si.isDynamic() + && !si.isDeclaredInManifest(), ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO, + callingPackage, launcherUserId, false); + } + // Get list of shortcuts that will get unpinned. + ArraySet<String> oldPinnedIds = launcher.getPinnedShortcutIds(packageName, userId); + + launcher.pinShortcuts(userId, packageName, shortcutIds, /*forPinRequest=*/ false); + + if (oldPinnedIds != null && removedShortcuts != null) { + for (int i = 0; i < removedShortcuts.size(); i++) { + oldPinnedIds.remove(removedShortcuts.get(i).getId()); } } + changedShortcuts = prepareChangedShortcuts( + oldPinnedIds, new ArraySet<>(shortcutIds), removedShortcuts, sp); } - // TODO: Include previously pinned shortcuts since they are not pinned anymore. - packageShortcutsChanged(packageName, userId, changedShortcuts, null); + + packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts); verifyStates(); } @@ -3045,17 +3114,17 @@ public class ShortcutService extends IShortcutService.Stub { + "shortcut " + si.getId()); } } else { - boolean removed = false; + ShortcutInfo removed = null; if (si.isDynamic()) { si.clearFlags(ShortcutInfo.FLAG_CACHED); } else { removed = sp.deleteLongLivedWithId(id, /*ignoreInvisible=*/ true); } - if (removed) { + if (removed != null) { if (removedShortcuts == null) { removedShortcuts = new ArrayList<>(1); } - removedShortcuts.add(si); + removedShortcuts.add(removed); } else { if (changedShortcuts == null) { changedShortcuts = new ArrayList<>(1); @@ -3222,8 +3291,6 @@ public class ShortcutService extends IShortcutService.Stub { // Grant read uri permission to the caller on behalf of the shortcut owner. All // granted permissions are revoked when the default launcher changes, or when // device is rebooted. - // b/151572645 is tracking a bug where Uri permissions are persisted across - // reboots, even when Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION is not used. mUriGrantsManager.grantUriPermissionFromOwner(mUriPermissionOwner, packageUid, launcherPackage, Uri.parse(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, userId, launcherUserId); @@ -4872,4 +4939,61 @@ public class ShortcutService extends IShortcutService.Stub { mShortcutBitmapSaver.waitForAllSavesLocked(); } } + + /** + * This helper method does the following 3 tasks: + * + * 1- Combines the |changed| and |updated| shortcut lists, while removing duplicates. + * 2- If a shortcut is deleted and added at once in the same operation, removes it from the + * |removed| list. + * 3- Reloads the final list to get the latest flags. + */ + private List<ShortcutInfo> prepareChangedShortcuts(ArraySet<String> changedIds, + ArraySet<String> newIds, List<ShortcutInfo> deletedList, final ShortcutPackage ps) { + if (ps == null) { + // This can happen when package restore is not finished yet. + return null; + } + if (CollectionUtils.isEmpty(changedIds) && CollectionUtils.isEmpty(newIds)) { + return null; + } + + ArraySet<String> resultIds = new ArraySet<>(); + if (!CollectionUtils.isEmpty(changedIds)) { + resultIds.addAll(changedIds); + } + if (!CollectionUtils.isEmpty(newIds)) { + resultIds.addAll(newIds); + } + + if (!CollectionUtils.isEmpty(deletedList)) { + deletedList.removeIf((ShortcutInfo si) -> resultIds.contains(si.getId())); + } + + List<ShortcutInfo> result = new ArrayList<>(); + ps.findAll(result, (ShortcutInfo si) -> resultIds.contains(si.getId()), + ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO); + return result; + } + + private List<ShortcutInfo> prepareChangedShortcuts(List<ShortcutInfo> changedList, + List<ShortcutInfo> newList, List<ShortcutInfo> deletedList, final ShortcutPackage ps) { + ArraySet<String> changedIds = new ArraySet<>(); + addShortcutIdsToSet(changedIds, changedList); + + ArraySet<String> newIds = new ArraySet<>(); + addShortcutIdsToSet(newIds, newList); + + return prepareChangedShortcuts(changedIds, newIds, deletedList, ps); + } + + private void addShortcutIdsToSet(ArraySet<String> ids, List<ShortcutInfo> shortcuts) { + if (CollectionUtils.isEmpty(shortcuts)) { + return; + } + final int size = shortcuts.size(); + for (int i = 0; i < size; i++) { + ids.add(shortcuts.get(i).getId()); + } + } } diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 1c1e64d70bbd..9a297d601a6b 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -370,24 +370,9 @@ public class StagingManager { } /** - * Perform snapshot and restore as required both for APEXes themselves and for apks in APEX. - * Apks inside apex are not installed using apk-install flow. They are scanned from the system - * directory directly by PackageManager, as such, RollbackManager need to handle their data - * separately here. + * Utility function for extracting apex sessions out of multi-package/single session. */ - private void snapshotAndRestoreForApexSession(PackageInstallerSession session) { - if (!sessionContainsApex(session)) { - return; - } - - boolean doSnapshotOrRestore = - (session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0 - || session.params.installReason == PackageManager.INSTALL_REASON_ROLLBACK; - if (!doSnapshotOrRestore) { - return; - } - - // Find all the apex sessions that needs processing + private List<PackageInstallerSession> extractApexSessions(PackageInstallerSession session) { List<PackageInstallerSession> apexSessions = new ArrayList<>(); if (session.isMultiPackage()) { List<PackageInstallerSession> childrenSessions = new ArrayList<>(); @@ -408,6 +393,50 @@ public class StagingManager { } else { apexSessions.add(session); } + return apexSessions; + } + + /** + * Checks if all apk-in-apex were installed without errors for all of the apex sessions. Throws + * error for any apk-in-apex failed to install. + * + * @throws PackageManagerException if any apk-in-apex failed to install + */ + private void checkInstallationOfApkInApexSuccessful(PackageInstallerSession session) + throws PackageManagerException { + final List<PackageInstallerSession> apexSessions = extractApexSessions(session); + if (apexSessions.isEmpty()) { + return; + } + + for (PackageInstallerSession apexSession : apexSessions) { + String packageName = apexSession.getPackageName(); + if (!mApexManager.isApkInApexInstallSuccess(packageName)) { + throw new PackageManagerException(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, + "Failed to install apk-in-apex of " + packageName); + } + } + } + + /** + * Perform snapshot and restore as required both for APEXes themselves and for apks in APEX. + * Apks inside apex are not installed using apk-install flow. They are scanned from the system + * directory directly by PackageManager, as such, RollbackManager need to handle their data + * separately here. + */ + private void snapshotAndRestoreForApexSession(PackageInstallerSession session) { + boolean doSnapshotOrRestore = + (session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0 + || session.params.installReason == PackageManager.INSTALL_REASON_ROLLBACK; + if (!doSnapshotOrRestore) { + return; + } + + // Find all the apex sessions that needs processing + final List<PackageInstallerSession> apexSessions = extractApexSessions(session); + if (apexSessions.isEmpty()) { + return; + } final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class); final int[] allUsers = um.getUserIds(); @@ -545,18 +574,19 @@ public class StagingManager { return; } + // Check if apex packages in the session failed to activate if (hasApex) { if (apexSessionInfo == null) { - String errorMsg = "apexd did not know anything about a staged session supposed to" - + " be activated"; + final String errorMsg = "apexd did not know anything about a staged session " + + "supposed to be activated"; session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMsg); abortCheckpoint(errorMsg); return; } if (isApexSessionFailed(apexSessionInfo)) { - String errorMsg = "APEX activation failed. Check logcat messages from apexd for " - + "more information."; + String errorMsg = "APEX activation failed. Check logcat messages from apexd " + + "for more information."; if (!TextUtils.isEmpty(mNativeFailureReason)) { errorMsg = "Session reverted due to crashing native process: " + mNativeFailureReason; @@ -567,21 +597,26 @@ public class StagingManager { return; } if (!apexSessionInfo.isActivated && !apexSessionInfo.isSuccess) { - // Apexd did not apply the session for some unknown reason. There is no guarantee - // that apexd will install it next time. Safer to proactively mark as failed. - String errorMsg = "Staged session " + session.sessionId + "at boot didn't " - + "activate nor fail. Marking it as failed anyway."; + // Apexd did not apply the session for some unknown reason. There is no + // guarantee that apexd will install it next time. Safer to proactively mark + // it as failed. + final String errorMsg = "Staged session " + session.sessionId + "at boot " + + "didn't activate nor fail. Marking it as failed anyway."; session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMsg); abortCheckpoint(errorMsg); return; } - snapshotAndRestoreForApexSession(session); - Slog.i(TAG, "APEX packages in session " + session.sessionId - + " were successfully activated. Proceeding with APK packages, if any"); } - // The APEX part of the session is activated, proceed with the installation of APKs. + // Handle apk and apk-in-apex installation try { + if (hasApex) { + checkInstallationOfApkInApexSuccessful(session); + snapshotAndRestoreForApexSession(session); + Slog.i(TAG, "APEX packages in session " + session.sessionId + + " were successfully activated. Proceeding with APK packages, if any"); + } + // The APEX part of the session is activated, proceed with the installation of APKs. Slog.d(TAG, "Installing APK packages in session " + session.sessionId); installApksInSession(session); } catch (PackageManagerException e) { diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 95a81f099e2d..3074250950f7 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -711,7 +711,7 @@ public class DexManager { for (String isa : getAppDexInstructionSets(info.primaryCpuAbi, info.secondaryCpuAbi)) { boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName, dexPath, userId, isa, /*primaryOrSplit*/ false, - searchResult.mOwningPackageName, + loadingPackage, PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT); update |= newUpdate; } diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 1d7d0388eb0a..cfa0449aaf33 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -31,7 +31,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.PackageManagerInternal; import android.content.pm.PermissionInfo; -import android.content.pm.Signature; import android.content.pm.parsing.component.ParsedPermission; import android.os.UserHandle; import android.util.Log; @@ -86,9 +85,6 @@ public final class BasePermission { String sourcePackageName; - // TODO: Can we get rid of this? Seems we only use some signature info from the setting - PackageSettingBase sourcePackageSetting; - int protectionLevel; ParsedPermission perm; @@ -130,12 +126,6 @@ public final class BasePermission { public String getSourcePackageName() { return sourcePackageName; } - public PackageSettingBase getSourcePackageSetting() { - return sourcePackageSetting; - } - public Signature[] getSourceSignatures() { - return sourcePackageSetting.getSignatures(); - } public int getType() { return type; } @@ -149,9 +139,6 @@ public final class BasePermission { public void setPermission(@Nullable ParsedPermission perm) { this.perm = perm; } - public void setSourcePackageSetting(PackageSettingBase sourcePackageSetting) { - this.sourcePackageSetting = sourcePackageSetting; - } public int[] computeGids(int userId) { if (perUser) { @@ -290,7 +277,6 @@ public final class BasePermission { return; } sourcePackageName = newPackageName; - sourcePackageSetting = null; perm = null; if (pendingPermissionInfo != null) { pendingPermissionInfo.packageName = newPackageName; @@ -319,10 +305,9 @@ public final class BasePermission { if (PackageManagerService.DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" + getName() + " pkg=" + getSourcePackageName() + " info=" + pendingPermissionInfo); - if (sourcePackageSetting == null && pendingPermissionInfo != null) { + if (pendingPermissionInfo != null) { final BasePermission tree = findPermissionTree(permissionTrees, name); if (tree != null && tree.perm != null) { - sourcePackageSetting = tree.sourcePackageSetting; perm = new ParsedPermission(tree.perm, pendingPermissionInfo, tree.perm.getPackageName(), name); uid = tree.uid; @@ -355,7 +340,6 @@ public final class BasePermission { if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { // It's a built-in permission and no owner, take ownership now p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED); - bp.sourcePackageSetting = pkgSetting; bp.perm = p; bp.uid = pkg.getUid(); bp.sourcePackageName = p.getPackageName(); @@ -378,7 +362,6 @@ public final class BasePermission { if (tree == null || tree.sourcePackageName.equals(p.getPackageName())) { p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED); - bp.sourcePackageSetting = pkgSetting; bp.perm = p; bp.uid = pkg.getUid(); bp.sourcePackageName = p.getPackageName(); @@ -639,9 +622,6 @@ public final class BasePermission { pw.print(" flags=0x"); pw.println(Integer.toHexString(perm.getFlags())); } } - if (sourcePackageSetting != null) { - pw.print(" packageSetting="); pw.println(sourcePackageSetting); - } if (READ_EXTERNAL_STORAGE.equals(name)) { pw.print(" enforced="); pw.println(readEnforced); 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 e4e526145167..a18f90b9913f 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -2499,24 +2499,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { synchronized (mLock) { ArraySet<String> newImplicitPermissions = new ArraySet<>(); - // TODO ntmyren: Remove once propagated to droidfood - int flagMask = PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED - | PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED; - int user = UserHandle.getUserId(pkg.getUid()); - final int N = pkg.getRequestedPermissions().size(); for (int i = 0; i < N; i++) { final String permName = pkg.getRequestedPermissions().get(i); final BasePermission bp = mSettings.getPermissionLocked(permName); - - // TODO ntmyren: Remove once propagated to droidfood - if (bp != null && !bp.isRuntime()) { - PermissionState permState = permissionsState.getInstallPermissionState(bp.name); - if (permState == null || (permState.getFlags() & flagMask) != 0) { - permissionsState.updatePermissionFlags(bp, user, flagMask, 0); - } - } - final boolean appSupportsRuntimePermissions = pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M; String upgradedActivityRecognitionPermission = null; @@ -2526,7 +2512,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + " checking " + permName + ": " + bp); } - if (bp == null || bp.getSourcePackageSetting() == null) { + if (bp == null || getSourcePackageSetting(bp) == null) { if (packageOfInterest == null || packageOfInterest.equals( pkg.getPackageName())) { if (DEBUG_PERMISSIONS) { @@ -3403,10 +3389,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { // - or its signing certificate is a previous signing certificate of the defining // package, and the defining package still trusts the old certificate for permissions // - or it shares the above relationships with the system package + final PackageParser.SigningDetails sourceSigningDetails = + getSourcePackageSigningDetails(bp); boolean allowed = - pkg.getSigningDetails().hasAncestorOrSelf( - bp.getSourcePackageSetting().getSigningDetails()) - || bp.getSourcePackageSetting().getSigningDetails().checkCapability( + pkg.getSigningDetails().hasAncestorOrSelf(sourceSigningDetails) + || sourceSigningDetails.checkCapability( pkg.getSigningDetails(), PackageParser.SigningDetails.CertCapabilities.PERMISSION) || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails()) @@ -3576,6 +3563,22 @@ public class PermissionManagerService extends IPermissionManager.Stub { return allowed; } + @NonNull + private PackageParser.SigningDetails getSourcePackageSigningDetails( + @NonNull BasePermission bp) { + final PackageSetting ps = getSourcePackageSetting(bp); + if (ps == null) { + return PackageParser.SigningDetails.UNKNOWN; + } + return ps.getSigningDetails(); + } + + @Nullable + private PackageSetting getSourcePackageSetting(@NonNull BasePermission bp) { + final String sourcePackageName = bp.getSourcePackageName(); + return mPackageManagerInt.getPackageSetting(sourcePackageName); + } + private static boolean isProfileOwner(int uid) { DevicePolicyManagerInternal dpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class); @@ -3991,7 +3994,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for * all volumes * @param flags Control permission for which apps should be updated - * @param allPackages All currently known packages * @param callback Callback to call after permission changes */ private void updatePermissions(final @Nullable String changingPkgName, @@ -4084,8 +4086,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (bp.isDynamic()) { bp.updateDynamicPermission(mSettings.mPermissionTrees.values()); } - if (bp.getSourcePackageSetting() == null - || !packageName.equals(bp.getSourcePackageName())) { + if (!packageName.equals(bp.getSourcePackageName())) { + // Not checking sourcePackageSetting because it can be null when + // the permission source package is the target package and the target package is + // being uninstalled, continue; } // The target package is the source of the current permission @@ -4103,7 +4107,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int userId = userIds[userIdNum]; mPackageManagerInt.forEachPackage((AndroidPackage p) -> revokePermissionFromPackageForUser(p.getPackageName(), - bp.getName(), userId, callback)); + bp.getName(), true, userId, callback)); } } it.remove(); @@ -4123,9 +4127,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { bp.getSourcePackageName()); synchronized (mLock) { if (sourcePkg != null && sourcePs != null) { - if (bp.getSourcePackageSetting() == null) { - bp.setSourcePackageSetting(sourcePs); - } continue; } Slog.w(TAG, "Removing dangling permission: " + bp.getName() @@ -4141,7 +4142,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { * Revoke a runtime permission from a package for a given user ID. */ private void revokePermissionFromPackageForUser(@NonNull String pName, - @NonNull String permissionName, int userId, @Nullable PermissionCallback callback) { + @NonNull String permissionName, boolean overridePolicy, int userId, + @Nullable PermissionCallback callback) { final ApplicationInfo appInfo = mPackageManagerInt.getApplicationInfo(pName, 0, Process.SYSTEM_UID, UserHandle.USER_SYSTEM); @@ -4156,7 +4158,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { revokeRuntimePermissionInternal( permissionName, pName, - false, + overridePolicy, Process.SYSTEM_UID, userId, callback); @@ -4200,8 +4202,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); while (it.hasNext()) { final BasePermission bp = it.next(); - if (bp.getSourcePackageSetting() == null - || !packageName.equals(bp.getSourcePackageName())) { + if (!packageName.equals(bp.getSourcePackageName())) { + // Not checking sourcePackageSetting because it can be null when + // the permission source package is the target package and the target package is + // being uninstalled, continue; } // The target package is the source of the current permission tree @@ -4227,9 +4231,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { bp.getSourcePackageName()); synchronized (mLock) { if (sourcePkg != null && sourcePs != null) { - if (bp.getSourcePackageSetting() == null) { - bp.setSourcePackageSetting(sourcePs); - } continue; } Slog.w(TAG, "Removing dangling permission tree: " + bp.getName() diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java index edb6d65bd96f..05879ec9545e 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java +++ b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java @@ -21,7 +21,6 @@ import static java.util.Collections.emptyList; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.PackageManager; -import android.content.pm.PackageParser; import android.content.pm.SharedLibraryInfo; import com.android.internal.util.DataClass; @@ -64,6 +63,12 @@ public class PackageStateUnserialized { } public PackageStateUnserialized setLastPackageUsageTimeInMills(int reason, long time) { + if (reason < 0) { + return this; + } + if (reason >= PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT) { + return this; + } getLastPackageUsageTimeInMills()[reason] = time; return this; } diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index 6ff1ba7e7dbb..92184e87a357 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -323,7 +323,7 @@ public final class PermissionPolicyService extends SystemService { // Force synchronization as permissions might have changed synchronizePermissionsAndAppOpsForUser(userId); - restoreReadPhoneStatePermissions(); + //restoreReadPhoneStatePermissions(userId); // Tell observers we are initialized for this user. if (callback != null) { @@ -335,11 +335,12 @@ public final class PermissionPolicyService extends SystemService { * Ensure READ_PHONE_STATE user sensitive flags are assigned properly * TODO ntmyren: Remove once propagated, and state is repaired */ - private void restoreReadPhoneStatePermissions() { + private void restoreReadPhoneStatePermissions(int userId) { PermissionControllerManager manager = new PermissionControllerManager(this.getContext(), Handler.getMain()); PackageManager pm = getContext().getPackageManager(); - List<PackageInfo> packageInfos = pm.getInstalledPackages(MATCH_ALL | GET_PERMISSIONS); + List<PackageInfo> packageInfos = pm.getInstalledPackagesAsUser( + MATCH_ALL | GET_PERMISSIONS, userId); for (int i = packageInfos.size() - 1; i >= 0; i--) { PackageInfo pI = packageInfos.get(i); if (pI.requestedPermissions == null) { diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java index 885f561d2a19..ece5a553fd95 100644 --- a/services/core/java/com/android/server/rollback/Rollback.java +++ b/services/core/java/com/android/server/rollback/Rollback.java @@ -27,6 +27,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; import android.content.pm.UserInfo; import android.content.pm.VersionedPackage; import android.content.rollback.PackageRollbackInfo; @@ -36,14 +37,19 @@ import android.os.Binder; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.os.UserManager; +import android.os.ext.SdkExtensions; import android.text.TextUtils; import android.util.IntArray; import android.util.Slog; +import android.util.SparseIntArray; import android.util.SparseLongArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IndentingPrintWriter; +import com.android.server.LocalServices; +import com.android.server.pm.parsing.pkg.AndroidPackage; import java.io.File; import java.io.IOException; @@ -53,6 +59,7 @@ import java.text.ParseException; import java.time.Instant; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** @@ -174,6 +181,11 @@ class Rollback { private int mNumPackageSessionsWithSuccess; /** + * The extension versions supported at the time of rollback creation. + */ + @NonNull private final SparseIntArray mExtensionVersions; + + /** * Constructs a new, empty Rollback instance. * * @param rollbackId the id of the rollback. @@ -182,9 +194,11 @@ class Rollback { * @param userId the user that performed the install with rollback enabled. * @param installerPackageName the installer package name from the original install session. * @param packageSessionIds the session ids for all packages in the install. + * @param extensionVersions the extension versions supported at the time of rollback creation */ Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, - String installerPackageName, int[] packageSessionIds) { + String installerPackageName, int[] packageSessionIds, + SparseIntArray extensionVersions) { this.info = new RollbackInfo(rollbackId, /* packages */ new ArrayList<>(), /* isStaged */ stagedSessionId != -1, @@ -197,11 +211,13 @@ class Rollback { mState = ROLLBACK_STATE_ENABLING; mTimestamp = Instant.now(); mPackageSessionIds = packageSessionIds != null ? packageSessionIds : new int[0]; + mExtensionVersions = Objects.requireNonNull(extensionVersions); } Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, String installerPackageName) { - this(rollbackId, backupDir, stagedSessionId, userId, installerPackageName, null); + this(rollbackId, backupDir, stagedSessionId, userId, installerPackageName, null, + new SparseIntArray(0)); } /** @@ -209,7 +225,7 @@ class Rollback { */ Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId, @RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress, - int userId, String installerPackageName) { + int userId, String installerPackageName, SparseIntArray extensionVersions) { this.info = info; mUserId = userId; mInstallerPackageName = installerPackageName; @@ -219,6 +235,7 @@ class Rollback { mState = state; mApkSessionId = apkSessionId; mRestoreUserDataInProgress = restoreUserDataInProgress; + mExtensionVersions = Objects.requireNonNull(extensionVersions); // TODO(b/120200473): Include this field during persistence. This field will be used to // decide which rollback to expire when ACTION_PACKAGE_REPLACED is received. Note persisting // this field is not backward compatible. We won't fix b/120200473 until S to minimize the @@ -283,6 +300,14 @@ class Rollback { } /** + * Returns the extension versions that were supported at the time that the rollback was created, + * as a mapping from SdkVersion to ExtensionVersion. + */ + SparseIntArray getExtensionVersions() { + return mExtensionVersions; + } + + /** * Returns true if the rollback is in the ENABLING state. */ boolean isEnabling() { @@ -451,6 +476,15 @@ class Rollback { return; } + if (containsApex() && wasCreatedAtLowerExtensionVersion()) { + PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); + if (extensionVersionReductionWouldViolateConstraint(mExtensionVersions, pmi)) { + sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, + "Rollback may violate a minExtensionVersion constraint"); + return; + } + } + // Get a context to use to install the downgraded version of the package. Context pkgContext; try { @@ -826,6 +860,56 @@ class Rollback { } } + /** + * Returns true if there is an app installed that specifies a minExtensionVersion greater + * than what was present at the time this Rollback was created. + */ + @VisibleForTesting + static boolean extensionVersionReductionWouldViolateConstraint( + SparseIntArray rollbackExtVers, PackageManagerInternal pmi) { + if (rollbackExtVers.size() == 0) { + return false; + } + List<String> packages = pmi.getPackageList().getPackageNames(); + for (int i = 0; i < packages.size(); i++) { + AndroidPackage pkg = pmi.getPackage(packages.get(i)); + SparseIntArray minExtVers = pkg.getMinExtensionVersions(); + if (minExtVers == null) { + continue; + } + for (int j = 0; j < rollbackExtVers.size(); j++) { + int minExt = minExtVers.get(rollbackExtVers.keyAt(j), -1); + if (rollbackExtVers.valueAt(j) < minExt) { + return true; + } + } + } + return false; + } + + /** + * Returns true if for any SDK version, the extension version recorded at the time of rollback + * creation is lower than the current extension version. + */ + private boolean wasCreatedAtLowerExtensionVersion() { + for (int i = 0; i < mExtensionVersions.size(); i++) { + if (SdkExtensions.getExtensionVersion(mExtensionVersions.keyAt(i)) + > mExtensionVersions.valueAt(i)) { + return true; + } + } + return false; + } + + private boolean containsApex() { + for (PackageRollbackInfo pkgInfo : info.getPackages()) { + if (pkgInfo.isApex()) { + return true; + } + } + return false; + } + void dump(IndentingPrintWriter ipw) { synchronized (mLock) { ipw.println(info.getRollbackId() + ":"); @@ -852,6 +936,12 @@ class Rollback { ipw.decreaseIndent(); ipw.println("-committedSessionId: " + info.getCommittedSessionId()); } + if (mExtensionVersions.size() > 0) { + ipw.println("-extensionVersions:"); + ipw.increaseIndent(); + ipw.println(mExtensionVersions.toString()); + ipw.decreaseIndent(); + } ipw.decreaseIndent(); } } diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index 83e99b008b68..6726cc829c81 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -41,6 +41,7 @@ import android.content.rollback.IRollbackManager; import android.content.rollback.RollbackInfo; import android.content.rollback.RollbackManager; import android.os.Binder; +import android.os.Build; import android.os.Environment; import android.os.Handler; import android.os.HandlerExecutor; @@ -49,12 +50,14 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.os.ext.SdkExtensions; import android.provider.DeviceConfig; import android.util.IntArray; import android.util.Log; import android.util.LongArrayQueue; import android.util.Slog; import android.util.SparseBooleanArray; +import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.DumpUtils; @@ -1274,16 +1277,29 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { if (parentSession.isStaged()) { rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId, userId, - installerPackageName, packageSessionIds); + installerPackageName, packageSessionIds, getExtensionVersions()); } else { rollback = mRollbackStore.createNonStagedRollback(rollbackId, userId, - installerPackageName, packageSessionIds); + installerPackageName, packageSessionIds, getExtensionVersions()); } mRollbacks.add(rollback); return rollback; } + private SparseIntArray getExtensionVersions() { + // This list must be updated whenever the current API level is increased, or should be + // replaced when we have another way of determining the relevant SDK versions. + final int[] relevantSdkVersions = { Build.VERSION_CODES.R }; + + SparseIntArray result = new SparseIntArray(relevantSdkVersions.length); + for (int i = 0; i < relevantSdkVersions.length; i++) { + result.put(relevantSdkVersions[i], + SdkExtensions.getExtensionVersion(relevantSdkVersions[i])); + } + return result; + } + /** * Returns the Rollback associated with the given session if parent or child session id matches. * Returns null if not found. diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java index f6d46e24246c..3601f1d94474 100644 --- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -36,9 +36,9 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.PowerManager; import android.os.SystemProperties; -import android.text.TextUtils; import android.util.ArraySet; import android.util.Slog; +import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.FrameworkStatsLog; @@ -56,9 +56,7 @@ import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; -import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Set; @@ -156,12 +154,11 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve PackageWatchdog.getInstance(mContext).scheduleCheckAndMitigateNativeCrashes(); } - List<Integer> rollbackIds = popLastStagedRollbackIds(); - Iterator<Integer> rollbackIterator = rollbackIds.iterator(); - while (rollbackIterator.hasNext()) { - int rollbackId = rollbackIterator.next(); - WatchdogRollbackLogger.logRollbackStatusOnBoot( - mContext, rollbackId, rollbackManager.getRecentlyCommittedRollbacks()); + SparseArray<String> rollbackIds = popLastStagedRollbackIds(); + for (int i = 0; i < rollbackIds.size(); i++) { + WatchdogRollbackLogger.logRollbackStatusOnBoot(mContext, + rollbackIds.keyAt(i), rollbackIds.valueAt(i), + rollbackManager.getRecentlyCommittedRollbacks()); } } @@ -224,7 +221,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve packageInstaller.getSessionInfo(sessionId); if (sessionInfo.isStagedSessionReady() && markStagedSessionHandled(rollbackId)) { mContext.unregisterReceiver(listener); - saveStagedRollbackId(rollbackId); + saveStagedRollbackId(rollbackId, logPackage); WatchdogRollbackLogger.logEvent(logPackage, FrameworkStatsLog .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED, @@ -268,39 +265,54 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve } } - private void saveStagedRollbackId(int stagedRollbackId) { + private void saveStagedRollbackId(int stagedRollbackId, @Nullable VersionedPackage logPackage) { + writeStagedRollbackId(mLastStagedRollbackIdsFile, stagedRollbackId, logPackage); + } + + static void writeStagedRollbackId(File file, int stagedRollbackId, + @Nullable VersionedPackage logPackage) { try { - FileOutputStream fos = new FileOutputStream( - mLastStagedRollbackIdsFile, /*append*/true); + FileOutputStream fos = new FileOutputStream(file, true); PrintWriter pw = new PrintWriter(fos); - pw.append(",").append(String.valueOf(stagedRollbackId)); + String logPackageName = logPackage != null ? logPackage.getPackageName() : ""; + pw.append(String.valueOf(stagedRollbackId)).append(",").append(logPackageName); + pw.println(); pw.flush(); FileUtils.sync(fos); pw.close(); } catch (IOException e) { Slog.e(TAG, "Failed to save last staged rollback id", e); + file.delete(); + } + } + + private SparseArray<String> popLastStagedRollbackIds() { + try { + return readStagedRollbackIds(mLastStagedRollbackIdsFile); + } finally { mLastStagedRollbackIdsFile.delete(); } } - private List<Integer> popLastStagedRollbackIds() { - try (BufferedReader reader = - new BufferedReader(new FileReader(mLastStagedRollbackIdsFile))) { - String line = reader.readLine(); - // line is of format : ",id1,id2,id3....,idn" - String[] sessionIdsStr = line.split(","); - ArrayList<Integer> result = new ArrayList<>(); - for (String sessionIdStr: sessionIdsStr) { - if (!TextUtils.isEmpty(sessionIdStr.trim())) { - result.add(Integer.parseInt(sessionIdStr)); + static SparseArray<String> readStagedRollbackIds(File file) { + SparseArray<String> result = new SparseArray<>(); + try { + String line; + BufferedReader reader = new BufferedReader(new FileReader(file)); + while ((line = reader.readLine()) != null) { + // Each line is of the format: "id,logging_package" + String[] values = line.trim().split(","); + String rollbackId = values[0]; + String logPackageName = ""; + if (values.length > 1) { + logPackageName = values[1]; } + result.put(Integer.parseInt(rollbackId), logPackageName); } - return result; } catch (Exception ignore) { - return Collections.emptyList(); - } finally { - mLastStagedRollbackIdsFile.delete(); + return new SparseArray<>(); } + return result; } diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java index 7b046c1aa3a6..c304302fc0b1 100644 --- a/services/core/java/com/android/server/rollback/RollbackStore.java +++ b/services/core/java/com/android/server/rollback/RollbackStore.java @@ -28,6 +28,7 @@ import android.content.rollback.PackageRollbackInfo.RestoreInfo; import android.content.rollback.RollbackInfo; import android.util.IntArray; import android.util.Slog; +import android.util.SparseIntArray; import android.util.SparseLongArray; import com.android.internal.annotations.GuardedBy; @@ -176,6 +177,32 @@ class RollbackStore { return ceSnapshotInodes; } + private static @NonNull JSONArray extensionVersionsToJson( + SparseIntArray extensionVersions) throws JSONException { + JSONArray array = new JSONArray(); + for (int i = 0; i < extensionVersions.size(); i++) { + JSONObject entryJson = new JSONObject(); + entryJson.put("sdkVersion", extensionVersions.keyAt(i)); + entryJson.put("extensionVersion", extensionVersions.valueAt(i)); + array.put(entryJson); + } + return array; + } + + private static @NonNull SparseIntArray extensionVersionsFromJson(JSONArray json) + throws JSONException { + if (json == null) { + return new SparseIntArray(0); + } + SparseIntArray extensionVersions = new SparseIntArray(json.length()); + for (int i = 0; i < json.length(); i++) { + JSONObject entry = json.getJSONObject(i); + extensionVersions.append( + entry.getInt("sdkVersion"), entry.getInt("extensionVersion")); + } + return extensionVersions; + } + private static JSONObject rollbackInfoToJson(RollbackInfo rollback) throws JSONException { JSONObject json = new JSONObject(); json.put("rollbackId", rollback.getRollbackId()); @@ -200,10 +227,10 @@ class RollbackStore { * backupDir assigned. */ Rollback createNonStagedRollback(int rollbackId, int userId, String installerPackageName, - int[] packageSessionIds) { + int[] packageSessionIds, SparseIntArray extensionVersions) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, -1, userId, installerPackageName, - packageSessionIds); + packageSessionIds, extensionVersions); } /** @@ -211,10 +238,11 @@ class RollbackStore { * backupDir assigned. */ Rollback createStagedRollback(int rollbackId, int stagedSessionId, int userId, - String installerPackageName, int[] packageSessionIds) { + String installerPackageName, int[] packageSessionIds, + SparseIntArray extensionVersions) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, stagedSessionId, userId, installerPackageName, - packageSessionIds); + packageSessionIds, extensionVersions); } /** @@ -272,6 +300,8 @@ class RollbackStore { dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress()); dataJson.put("userId", rollback.getUserId()); dataJson.putOpt("installerPackageName", rollback.getInstallerPackageName()); + dataJson.putOpt( + "extensionVersions", extensionVersionsToJson(rollback.getExtensionVersions())); PrintWriter pw = new PrintWriter(new File(rollback.getBackupDir(), "rollback.json")); pw.println(dataJson.toString()); @@ -316,7 +346,8 @@ class RollbackStore { dataJson.getInt("apkSessionId"), dataJson.getBoolean("restoreUserDataInProgress"), dataJson.optInt("userId", USER_SYSTEM), - dataJson.optString("installerPackageName", "")); + dataJson.optString("installerPackageName", ""), + extensionVersionsFromJson(dataJson.optJSONArray("extensionVersions"))); } private static JSONObject toJson(VersionedPackage pkg) throws JSONException { diff --git a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java index 659de0093ead..e72c185a0d2d 100644 --- a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java +++ b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java @@ -36,6 +36,7 @@ import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.content.rollback.PackageRollbackInfo; import android.content.rollback.RollbackInfo; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Slog; @@ -43,7 +44,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; import com.android.server.PackageWatchdog; -import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -115,7 +115,7 @@ public final class WatchdogRollbackLogger { } - static void logRollbackStatusOnBoot(Context context, int rollbackId, + static void logRollbackStatusOnBoot(Context context, int rollbackId, String logPackageName, List<RollbackInfo> recentlyCommittedRollbacks) { PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); @@ -132,23 +132,15 @@ public final class WatchdogRollbackLogger { return; } - // Identify the logging parent for this rollback. When all configurations are correct, - // each package in the rollback has a logging parent set in metadata. - final Set<String> loggingPackageNames = new ArraySet<>(); - for (PackageRollbackInfo packageRollback : rollback.getPackages()) { - final String loggingParentName = getLoggingParentName(context, - packageRollback.getPackageName()); - if (loggingParentName != null) { - loggingPackageNames.add(loggingParentName); - } - } - // Use the version of the logging parent that was installed before // we rolled back for logging purposes. - final List<VersionedPackage> oldLoggingPackages = new ArrayList<>(); - for (PackageRollbackInfo packageRollback : rollback.getPackages()) { - if (loggingPackageNames.contains(packageRollback.getPackageName())) { - oldLoggingPackages.add(packageRollback.getVersionRolledBackFrom()); + VersionedPackage oldLoggingPackage = null; + if (!TextUtils.isEmpty(logPackageName)) { + for (PackageRollbackInfo packageRollback : rollback.getPackages()) { + if (logPackageName.equals(packageRollback.getPackageName())) { + oldLoggingPackage = packageRollback.getVersionRolledBackFrom(); + break; + } } } @@ -159,22 +151,14 @@ public final class WatchdogRollbackLogger { return; } - // If no logging packages are found, use a null package to ensure the rollback status - // is still logged. - if (oldLoggingPackages.isEmpty()) { - oldLoggingPackages.add(null); - } - - for (VersionedPackage oldLoggingPackage : oldLoggingPackages) { - if (sessionInfo.isStagedSessionApplied()) { - logEvent(oldLoggingPackage, - WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS, - WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, ""); - } else if (sessionInfo.isStagedSessionFailed()) { - logEvent(oldLoggingPackage, - WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, - WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, ""); - } + if (sessionInfo.isStagedSessionApplied()) { + logEvent(oldLoggingPackage, + WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS, + WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, ""); + } else if (sessionInfo.isStagedSessionFailed()) { + logEvent(oldLoggingPackage, + WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, + WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, ""); } } diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java index ec394a224cd7..4bc774413ac0 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java @@ -47,6 +47,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; /** * This is a decorator of an {@link ISoundTriggerMiddlewareService}, which enforces permissions and @@ -123,7 +124,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware } } - private Boolean mCaptureState; + private AtomicReference<Boolean> mCaptureState = new AtomicReference<>(); private final @NonNull ISoundTriggerMiddlewareInternal mDelegate; private final @NonNull Context mContext; @@ -230,10 +231,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware } catch (Exception e) { throw handleException(e); } finally { - // It is safe to lock here - local operation. - synchronized (this) { - mCaptureState = active; - } + mCaptureState.set(active); } } @@ -286,8 +284,9 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware @Override public void dump(PrintWriter pw) { synchronized (this) { - pw.printf("Capture state is %s\n\n", mCaptureState == null ? "uninitialized" - : (mCaptureState ? "active" : "inactive")); + Boolean captureState = mCaptureState.get(); + pw.printf("Capture state is %s\n\n", captureState == null ? "uninitialized" + : (captureState ? "active" : "inactive")); if (mModules != null) { for (int handle : mModules.keySet()) { final ModuleState module = mModules.get(handle); 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 299592d33a11..373cb8be9c66 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -2951,7 +2951,7 @@ public class StatsPullAtomService extends SystemService { } int processHistoricalOps(HistoricalOps histOps, int atomTag, List<StatsEvent> pulledData) { - int counter = 0; + int counter = 1; for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) { final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx); final int uid = uidOps.getUid(); diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java index c207a7b4039b..c18a6ebc32ef 100644 --- a/services/core/java/com/android/server/storage/StorageUserConnection.java +++ b/services/core/java/com/android/server/storage/StorageUserConnection.java @@ -242,7 +242,13 @@ public final class StorageUserConnection { } if (oldConnection != null) { - mContext.unbindService(oldConnection); + try { + mContext.unbindService(oldConnection); + } catch (Exception e) { + // Handle IllegalArgumentException that may be thrown if the user is already + // stopped when we try to unbind + Slog.w(TAG, "Failed to unbind service", e); + } } } diff --git a/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java b/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java index 7fe4bf849443..b77df2d18859 100644 --- a/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java +++ b/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java @@ -408,7 +408,12 @@ public class CountQuotaTracker extends QuotaTracker { void updateExecutionStatsLocked(final int userId, @NonNull final String packageName, @Nullable final String tag, @NonNull ExecutionStats stats) { stats.countInWindow = 0; - stats.inQuotaTimeElapsed = 0; + if (stats.countLimit == 0) { + // UPTC won't be in quota until configuration changes. + stats.inQuotaTimeElapsed = Long.MAX_VALUE; + } else { + stats.inQuotaTimeElapsed = 0; + } // This can be used to determine when an app will have enough quota to transition from // out-of-quota to in-quota. diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 130da2dfe9c5..dcdbfdedb0c8 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2669,15 +2669,28 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return this; } - // Ensure activity visibilities and update lockscreen occluded/dismiss state when - // finishing the top activity that occluded keyguard. So that, the - // ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below won't - // be resumed. - if (isState(PAUSED) - && mStackSupervisor.getKeyguardController().isKeyguardLocked() - && getStack().topActivityOccludesKeyguard()) { - getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, - false /* preserveWindows */, false /* notifyClients */); + final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED); + if (isCurrentVisible) { + final ActivityStack stack = getStack(); + final ActivityRecord activity = stack.mResumedActivity; + boolean ensureVisibility = false; + if (activity != null && !activity.occludesParent()) { + // If the resume activity is not opaque, we need to make sure the visibilities of + // activities be updated, they may be seen by users. + ensureVisibility = true; + } else if (mStackSupervisor.getKeyguardController().isKeyguardLocked() + && stack.topActivityOccludesKeyguard()) { + // Ensure activity visibilities and update lockscreen occluded/dismiss state when + // finishing the top activity that occluded keyguard. So that, the + // ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below + // won't be resumed. + ensureVisibility = true; + } + + if (ensureVisibility) { + getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + false /* preserveWindows */, true /* notifyClients */); + } } boolean activityRemoved = false; @@ -2698,7 +2711,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // than destroy immediately. final boolean isNextNotYetVisible = next != null && (!next.nowVisible || !next.mVisibleRequested); - if ((mVisibleRequested || isState(PAUSED)) && isNextNotYetVisible) { + if (isCurrentVisible && isNextNotYetVisible) { // Add this activity to the list of stopping activities. It will be processed and // destroyed when the next activity reports idle. addToStopping(false /* scheduleIdle */, false /* idleDelayed */, diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 8edc84fc8f37..4ea990285269 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -61,6 +61,7 @@ import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; @@ -108,6 +109,7 @@ import android.os.UserManager; import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.util.ArraySet; +import android.util.DebugUtils; import android.util.Pools.SynchronizedPool; import android.util.Slog; @@ -1195,6 +1197,9 @@ class ActivityStarter { final int callingAppId = UserHandle.getAppId(callingUid); if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID || callingAppId == Process.NFC_UID) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Activity start allowed for important callingUid (" + callingUid + ")"); + } return false; } @@ -1208,6 +1213,11 @@ class ActivityStarter { final boolean isCallingUidPersistentSystemProcess = callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid + + ", isCallingUidPersistentSystemProcess = " + + isCallingUidPersistentSystemProcess); + } return false; } // take realCallingUid into consideration @@ -1229,35 +1239,66 @@ class ActivityStarter { if (realCallingUid != callingUid) { // don't abort if the realCallingUid has a visible window if (realCallingUidHasAnyVisibleWindow) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + + ") has visible (non-toast) window"); + } return false; } // if the realCallingUid is a persistent system process, abort if the IntentSender // wasn't whitelisted to start an activity if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + + ") is persistent system process AND intent sender whitelisted " + + "(allowBackgroundActivityStart = true)"); + } return false; } // don't abort if the realCallingUid is an associated companion app if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid), realCallingUid)) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + + ") is companion app"); + } return false; } } // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) == PERMISSION_GRANTED) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, + "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND " + + "permission granted for uid " + + callingUid); + } return false; } // don't abort if the caller has the same uid as the recents component if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid + + ") is recents"); + } return false; } // don't abort if the callingUid is the device owner if (mService.isDeviceOwner(callingUid)) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid + + ") is device owner"); + } return false; } // don't abort if the callingUid has companion device final int callingUserId = UserHandle.getUserId(callingUid); if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid + + ") is companion app"); + } return false; } // If we don't have callerApp at this point, no caller was provided to startActivity(). @@ -1273,6 +1314,10 @@ class ActivityStarter { if (callerApp != null) { // first check the original calling process if (callerApp.areBackgroundActivityStartsAllowed()) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Background activity start allowed: callerApp process (pid = " + + callerApp.getPid() + ", uid = " + callerAppUid + ") is whitelisted"); + } return false; } // only if that one wasn't whitelisted, check the other ones @@ -1282,6 +1327,11 @@ class ActivityStarter { for (int i = uidProcesses.size() - 1; i >= 0; i--) { final WindowProcessController proc = uidProcesses.valueAt(i); if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, + "Background activity start allowed: process " + proc.getPid() + + " from uid " + callerAppUid + " is whitelisted"); + } return false; } } @@ -1297,9 +1347,15 @@ class ActivityStarter { Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage + "; callingUid: " + callingUid + "; isCallingUidForeground: " + isCallingUidForeground + + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow + + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, + "PROCESS_STATE_", callingUidProcState) + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess + "; realCallingUid: " + realCallingUid + "; isRealCallingUidForeground: " + isRealCallingUidForeground + + "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow + + "; realCallingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, + "PROCESS_STATE_", realCallingUidProcState) + "; isRealCallingUidPersistentSystemProcess: " + isRealCallingUidPersistentSystemProcess + "; originatingPendingIntent: " + originatingPendingIntent @@ -1384,7 +1440,8 @@ class ActivityStarter { final ActivityStack homeStack = targetTask.getDisplayArea().getRootHomeTask(); final boolean homeTaskVisible = homeStack != null && homeStack.shouldBeVisible(null); mService.getTaskChangeNotificationController().notifyActivityRestartAttempt( - targetTask.getTaskInfo(), homeTaskVisible, clearedTask); + targetTask.getTaskInfo(), homeTaskVisible, clearedTask, + targetTask.getTopNonFinishingActivity().isVisible()); } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java index 7f09a071308a..da0bfd67e353 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java @@ -65,6 +65,7 @@ public class ActivityTaskManagerDebugConfig { static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false; static final boolean DEBUG_PERMISSIONS_REVIEW = DEBUG_ALL || false; static final boolean DEBUG_RESULTS = DEBUG_ALL || false; + static final boolean DEBUG_ACTIVITY_STARTS = DEBUG_ALL || false; public static final boolean DEBUG_CLEANUP = DEBUG_ALL || false; public static final boolean DEBUG_METRICS = DEBUG_ALL || false; diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index 537ca08f49fc..5efc9241a494 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -382,8 +382,8 @@ class Dimmer { @Override public void apply(SurfaceControl.Transaction t, SurfaceControl sc, long currentPlayTime) { - float alpha = ((float) currentPlayTime / getDuration()) * (mToAlpha - mFromAlpha) - + mFromAlpha; + final float fraction = getFraction(currentPlayTime); + final float alpha = fraction * (mToAlpha - mFromAlpha) + mFromAlpha; t.setAlpha(sc, alpha); } diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 9b34bd17d042..345cfb0aad71 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -140,8 +140,12 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { void setOrganizer(IDisplayAreaOrganizer organizer) { if (mOrganizer == organizer) return; - sendDisplayAreaVanished(); + IDisplayAreaOrganizer lastOrganizer = mOrganizer; + // Update the new display area organizer before calling sendDisplayAreaVanished since it + // could result in a new SurfaceControl getting created that would notify the old organizer + // about it. mOrganizer = organizer; + sendDisplayAreaVanished(lastOrganizer); sendDisplayAreaAppeared(); } @@ -150,9 +154,10 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { mOrganizerController.onDisplayAreaAppeared(mOrganizer, this); } - void sendDisplayAreaVanished() { - if (mOrganizer == null) return; - mOrganizerController.onDisplayAreaVanished(mOrganizer, this); + void sendDisplayAreaVanished(IDisplayAreaOrganizer organizer) { + if (organizer == null) return; + migrateToNewSurfaceControl(); + mOrganizerController.onDisplayAreaVanished(organizer, this); } @Override @@ -171,7 +176,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { DisplayAreaInfo getDisplayAreaInfo() { DisplayAreaInfo info = new DisplayAreaInfo(mRemoteToken.toWindowContainerToken(), - getDisplayContent().getDisplayId()); + getDisplayContent().getDisplayId(), mFeatureId); info.configuration.setTo(getConfiguration()); return info; } diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java index 2c8c8201c534..b6c71bb17631 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java +++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java @@ -21,6 +21,7 @@ import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.view.SurfaceControl; import android.window.IDisplayAreaOrganizer; import android.window.IDisplayAreaOrganizerController; @@ -113,7 +114,8 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) { try { - organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo()); + SurfaceControl outSurfaceControl = new SurfaceControl(da.getSurfaceControl()); + organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo(), outSurfaceControl); } catch (RemoteException e) { // Oh well... } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c41029b20651..c66ff330edbd 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -494,10 +494,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * The launching activity which is using fixed rotation transformation. * * @see #handleTopActivityLaunchingInDifferentOrientation + * @see #setFixedRotationLaunchingApp * @see DisplayRotation#shouldRotateSeamlessly */ ActivityRecord mFixedRotationLaunchingApp; + final FixedRotationTransitionListener mFixedRotationTransitionListener = + new FixedRotationTransitionListener(); + /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */ final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>(); @@ -928,6 +932,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mAppTransition = new AppTransition(mWmService.mContext, mWmService, this); mAppTransition.registerListenerLocked(mWmService.mActivityManagerAppTransitionNotifier); + mAppTransition.registerListenerLocked(mFixedRotationTransitionListener); mAppTransitionController = new AppTransitionController(mWmService, this); mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this); @@ -1266,6 +1271,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (configUpdated) { return; } + + // The display configuration doesn't change. If there is a launching transformed app, that + // means its request to change display configuration has been discarded, then it should + // respect to the current configuration of display. + clearFixedRotationLaunchingApp(); + // Something changed (E.g. device rotation), but no configuration update is needed. // E.g. changing device rotation by 180 degrees. Go ahead and perform surface placement to // unfreeze the display since we froze it when the rotation was updated in @@ -1383,7 +1394,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo orientationSource != null ? orientationSource.asActivityRecord() : null; // Currently there is no use case from non-activity. if (r != null && handleTopActivityLaunchingInDifferentOrientation(r)) { - mFixedRotationLaunchingApp = r; // Display orientation should be deferred until the top fixed rotation is finished. return false; } @@ -1448,47 +1458,66 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return false; } - startFixedRotationTransform(r, rotation); - mAppTransition.registerListenerLocked(new WindowManagerInternal.AppTransitionListener() { - void done() { - r.finishFixedRotationTransform(); - mAppTransition.unregisterListener(this); - } - - @Override - public void onAppTransitionFinishedLocked(IBinder token) { - if (token == r.token) { - done(); - } - } + setFixedRotationLaunchingApp(r, rotation); + return true; + } - @Override - public void onAppTransitionCancelledLocked(int transit) { - done(); - } + /** + * Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed + * rotation transform to it and indicate that the display may be rotated after it is launched. + */ + void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Surface.Rotation int rotation) { + final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp; + if (prevRotatedLaunchingApp != null + && prevRotatedLaunchingApp.getWindowConfiguration().getRotation() == rotation + // It is animating so we can expect there will have a transition callback. + && prevRotatedLaunchingApp.isAnimating(TRANSITION | PARENTS)) { + // It may be the case that multiple activities launch consecutively. Because their + // rotation are the same, the transformed state can be shared to avoid duplicating + // the heavy operations. This also benefits that the states of multiple activities + // are handled together. + r.linkFixedRotationTransform(prevRotatedLaunchingApp); + return; + } - @Override - public void onAppTransitionTimeoutLocked() { - done(); - } - }); - return true; + if (!r.hasFixedRotationTransform()) { + startFixedRotationTransform(r, rotation); + } + mFixedRotationLaunchingApp = r; + if (prevRotatedLaunchingApp != null) { + prevRotatedLaunchingApp.finishFixedRotationTransform(); + } } - /** @return {@code true} if the display orientation will be changed. */ - boolean continueUpdateOrientationForDiffOrienLaunchingApp(WindowToken token) { - if (token != mFixedRotationLaunchingApp) { - return false; + /** + * Continue updating the orientation change of display if it was deferred by a top activity + * launched in a different orientation. + */ + void continueUpdateOrientationForDiffOrienLaunchingApp() { + if (mFixedRotationLaunchingApp == null) { + return; } // Update directly because the app which will change the orientation of display is ready. if (mDisplayRotation.updateOrientation(getOrientation(), false /* forceUpdate */)) { sendNewConfiguration(); - return true; + return; + } + // The orientation of display is not changed. + clearFixedRotationLaunchingApp(); + } + + /** + * Clears the {@link mFixedRotationLaunchingApp} without applying rotation to display. It is + * used when the display won't rotate (e.g. the orientation from sensor has updated again before + * applying rotation to display) but the launching app has been transformed. So the record need + * to be cleared and restored to stop using seamless rotation and rotated configuration. + */ + private void clearFixedRotationLaunchingApp() { + if (mFixedRotationLaunchingApp == null) { + return; } - // The display won't rotate (e.g. the orientation from sensor has updated again before - // applying rotation to display), so clear it to stop using seamless rotation. + mFixedRotationLaunchingApp.finishFixedRotationTransform(); mFixedRotationLaunchingApp = null; - return false; } private void startFixedRotationTransform(WindowToken token, int rotation) { @@ -2858,6 +2887,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo pw.print(" mLastStatusBarVisibility=0x"); pw.println(Integer.toHexString(mLastStatusBarVisibility)); } + if (mFixedRotationLaunchingApp != null) { + pw.println(" mFixedRotationLaunchingApp=" + mFixedRotationLaunchingApp); + } pw.println(); mWallpaperController.dump(pw, " "); @@ -5184,7 +5216,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int currRotation = currOverrideConfig.windowConfiguration.getRotation(); final int overrideRotation = overrideConfiguration.windowConfiguration.getRotation(); if (currRotation != ROTATION_UNDEFINED && currRotation != overrideRotation) { - applyRotationAndClearFixedRotation(currRotation, overrideRotation); + applyRotationAndFinishFixedRotation(currRotation, overrideRotation); } mCurrentOverrideConfigurationChanges = currOverrideConfig.diff(overrideConfiguration); super.onRequestedOverrideConfigurationChanged(overrideConfiguration); @@ -5200,7 +5232,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * fixed rotation transform also needs to be cleared to make sure the rotated activity fits * the display naturally. */ - private void applyRotationAndClearFixedRotation(int oldRotation, int newRotation) { + private void applyRotationAndFinishFixedRotation(int oldRotation, int newRotation) { if (mFixedRotationLaunchingApp == null) { applyRotation(oldRotation, newRotation); return; @@ -5219,7 +5251,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } }); - mFixedRotationLaunchingApp.clearFixedRotationTransform( + mFixedRotationLaunchingApp.finishFixedRotationTransform( () -> applyRotation(oldRotation, newRotation)); mFixedRotationLaunchingApp = null; } @@ -5494,6 +5526,75 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo }); } + /** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */ + class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener { + + /** + * The animating activity which shows the recents task list. It is set between + * {@link RecentsAnimationController#initialize} and + * {@link RecentsAnimationController#cancelAnimation}. + */ + private ActivityRecord mAnimatingRecents; + + /** + * If the recents activity has a fixed orientation which is different from the current top + * activity, it will be rotated before being shown so we avoid a screen rotation animation + * when showing the Recents view. + */ + void onStartRecentsAnimation(@NonNull ActivityRecord r) { + mAnimatingRecents = r; + rotateInDifferentOrientationIfNeeded(r); + if (r.hasFixedRotationTransform()) { + // Set the record so we can recognize it to continue to update display orientation + // if the recents activity becomes the top later. + setFixedRotationLaunchingApp(r, r.getWindowConfiguration().getRotation()); + } + } + + /** + * If {@link #mAnimatingRecents} still has fixed rotation, it should be moved to top so we + * don't clear {@link #mFixedRotationLaunchingApp} that will be handled by transition. + */ + void onFinishRecentsAnimation() { + final ActivityRecord animatingRecents = mAnimatingRecents; + mAnimatingRecents = null; + if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp + && !animatingRecents.hasFixedRotationTransform()) { + // The recents activity won't be the top, such as giving up the swipe up gesture + // and return to the original top. + mFixedRotationLaunchingApp = null; + } + } + + @Override + public void onAppTransitionFinishedLocked(IBinder token) { + final ActivityRecord r = getActivityRecord(token); + // Ignore the animating recents so the fixed rotation transform won't be switched twice + // by finishing the recents animation and moving it to top. That also avoids flickering + // due to wait for previous activity to be paused if it supports PiP that ignores the + // effect of resume-while-pausing. + if (r == null || r == mAnimatingRecents) { + return; + } + if (mFixedRotationLaunchingApp != null + && mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) { + continueUpdateOrientationForDiffOrienLaunchingApp(); + } else { + r.finishFixedRotationTransform(); + } + } + + @Override + public void onAppTransitionCancelledLocked(int transit) { + continueUpdateOrientationForDiffOrienLaunchingApp(); + } + + @Override + public void onAppTransitionTimeoutLocked() { + continueUpdateOrientationForDiffOrienLaunchingApp(); + } + } + class RemoteInsetsControlTarget implements InsetsControlTarget { private final IDisplayWindowInsetsController mRemoteInsetsController; diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 656dca531a22..1b1898b76506 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -27,7 +27,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.graphics.Rect; @@ -38,7 +37,6 @@ import android.os.Process; import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; -import android.util.Log; import android.util.Slog; import android.view.InputApplicationHandle; import android.view.InputChannel; @@ -138,18 +136,6 @@ final class InputMonitor { // If there's a drag in flight, provide a pseudo-window to catch drag input final boolean inDrag = mService.mDragDropController.dragDropActiveLocked(); - final boolean inPositioning = - mService.mTaskPositioningController.isPositioningLocked(); - if (inPositioning) { - if (DEBUG_TASK_POSITIONING) { - Log.d(TAG_WM, "Inserting window handle for repositioning"); - } - mService.mTaskPositioningController.showInputSurface(mInputTransaction, - mDisplayId); - } else { - mService.mTaskPositioningController.hideInputSurface(mInputTransaction, - mDisplayId); - } // Add all windows on the default display. mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag); diff --git a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java index 7c1a6161236a..f0629fa953fc 100644 --- a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java +++ b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java @@ -130,6 +130,16 @@ class LocalAnimationAdapter implements AnimationAdapter { */ default boolean needsEarlyWakeup() { return false; } + /** + * @return The fraction of the animation, returns 1 if duration is 0. + * + * @param currentPlayTime The current play time. + */ + default float getFraction(float currentPlayTime) { + final float duration = getDuration(); + return duration > 0 ? currentPlayTime / duration : 1.0f; + } + void dump(PrintWriter pw, String prefix); default void dumpDebug(ProtoOutputStream proto, long fieldId) { diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 6efa8de86c28..dd761bec0f16 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -411,10 +411,7 @@ public class RecentsAnimationController implements DeathRecipient { mService.mWindowPlacerLocked.performSurfacePlacement(); - // If the target activity has a fixed orientation which is different from the current top - // activity, it will be rotated before being shown so we avoid a screen rotation - // animation when showing the Recents view. - mDisplayContent.rotateInDifferentOrientationIfNeeded(mTargetActivityRecord); + mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(targetActivity); // Notify that the animation has started if (mStatusBar != null) { @@ -736,11 +733,13 @@ public class RecentsAnimationController implements DeathRecipient { if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) { mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked( mTargetActivityRecord.token); - } - if (mTargetActivityRecord.hasFixedRotationTransform()) { + } else { + // The target activity will be moved to original position (non-top). Since it won't + // affect display orientation, just finish the transform. mTargetActivityRecord.finishFixedRotationTransform(); } } + mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(); // Notify that the animation has ended if (mStatusBar != null) { diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index 86e081854597..90936efe6715 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -646,8 +646,8 @@ class ScreenRotationAnimation { @Override public void apply(SurfaceControl.Transaction t, SurfaceControl leash, long currentPlayTime) { - float fraction = (float)currentPlayTime / (float)getDuration(); - int color = (Integer) va.evaluate(fraction, startColor, endColor); + final float fraction = getFraction(currentPlayTime); + final int color = (Integer) va.evaluate(fraction, startColor, endColor); Color middleColor = Color.valueOf(color); rgbTmpFloat[0] = middleColor.red(); rgbTmpFloat[1] = middleColor.green(); diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java index 0b1760dc5a1c..99f710bd8bd4 100644 --- a/services/core/java/com/android/server/wm/ShellRoot.java +++ b/services/core/java/com/android/server/wm/ShellRoot.java @@ -43,6 +43,8 @@ public class ShellRoot { private WindowToken mToken; private final IBinder.DeathRecipient mDeathRecipient; private SurfaceControl mSurfaceControl = null; + private IWindow mAccessibilityWindow; + private IBinder.DeathRecipient mAccessibilityWindowDeath; ShellRoot(@NonNull IWindow client, @NonNull DisplayContent dc, final int windowType) { mDisplayContent = dc; @@ -112,11 +114,14 @@ public class ShellRoot { if (!mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()) { return null; } + if (mAccessibilityWindow == null) { + return null; + } WindowInfo windowInfo = WindowInfo.obtain(); windowInfo.displayId = mToken.getDisplayArea().getDisplayContent().mDisplayId; windowInfo.type = mToken.windowType; windowInfo.layer = mToken.getWindowLayerFromType(); - windowInfo.token = mClient.asBinder(); + windowInfo.token = mAccessibilityWindow.asBinder(); windowInfo.title = "Splitscreen Divider"; windowInfo.focused = false; windowInfo.inPictureInPicture = false; @@ -126,5 +131,29 @@ public class ShellRoot { windowInfo.regionInScreen.set(regionRect); return windowInfo; } + + void setAccessibilityWindow(IWindow window) { + if (mAccessibilityWindow != null) { + mAccessibilityWindow.asBinder().unlinkToDeath(mAccessibilityWindowDeath, 0); + } + mAccessibilityWindow = window; + if (mAccessibilityWindow != null) { + try { + mAccessibilityWindowDeath = () -> { + synchronized (mDisplayContent.mWmService.mGlobalLock) { + mAccessibilityWindow = null; + setAccessibilityWindow(null); + } + }; + mAccessibilityWindow.asBinder().linkToDeath(mAccessibilityWindowDeath, 0); + } catch (RemoteException e) { + mAccessibilityWindow = null; + } + } + if (mDisplayContent.mWmService.mAccessibilityController != null) { + mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked( + mDisplayContent.getDisplayId()); + } + } } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 2115a591a6b7..8f8ca7707eb5 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -644,7 +644,7 @@ class Task extends WindowContainer<WindowContainer> { return; } removeImmediately(); - if (!isRootTask) { + if (isLeafTask()) { mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId); } } @@ -1431,15 +1431,15 @@ class Task extends WindowContainer<WindowContainer> { @Override void removeChild(WindowContainer child) { - // A rootable child task that is now being removed from an organized task. Making sure - // the stack references is keep updated. - if (mTaskOrganizer != null && mCreatedByOrganizer && child.asTask() != null) { - getDisplayArea().removeStackReferenceIfNeeded((ActivityStack) child); - } removeChild(child, "removeChild"); } void removeChild(WindowContainer r, String reason) { + // A rootable child task that is now being removed from an organized task. Making sure + // the stack references is keep updated. + if (mTaskOrganizer != null && mCreatedByOrganizer && r.asTask() != null) { + getDisplayArea().removeStackReferenceIfNeeded((ActivityStack) r); + } if (!mChildren.contains(r)) { Slog.e(TAG, "removeChild: r=" + r + " not found in t=" + this); return; @@ -1930,9 +1930,11 @@ class Task extends WindowContainer<WindowContainer> { // Check if the new configuration supports persistent bounds (eg. is Freeform) and if so // restore the last recorded non-fullscreen bounds. final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds(); - final boolean nextPersistTaskBounds = - getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds() - || newParentConfig.windowConfiguration.persistTaskBounds(); + boolean nextPersistTaskBounds = + getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds(); + if (getRequestedOverrideWindowingMode() == WINDOWING_MODE_UNDEFINED) { + nextPersistTaskBounds = newParentConfig.windowConfiguration.persistTaskBounds(); + } if (!prevPersistTaskBounds && nextPersistTaskBounds && mLastNonFullscreenBounds != null && !mLastNonFullscreenBounds.isEmpty()) { // Bypass onRequestedOverrideConfigurationChanged here to avoid infinite loop. @@ -2004,6 +2006,14 @@ class Task extends WindowContainer<WindowContainer> { return (prevWinMode == WINDOWING_MODE_FREEFORM) != (newWinMode == WINDOWING_MODE_FREEFORM); } + @Override + void migrateToNewSurfaceControl() { + super.migrateToNewSurfaceControl(); + mLastSurfaceSize.x = 0; + mLastSurfaceSize.y = 0; + updateSurfaceSize(getPendingTransaction()); + } + void updateSurfaceSize(SurfaceControl.Transaction transaction) { if (mSurfaceControl == null || mCreatedByOrganizer) { return; @@ -2299,27 +2309,31 @@ class Task extends WindowContainer<WindowContainer> { insideParentBounds = parentBounds.contains(resolvedBounds); } + // Non-null compatibility insets means the activity prefers to keep its original size, so + // out bounds doesn't need to be restricted by the parent or current display + final boolean customContainerPolicy = compatInsets != null; + Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); if (outAppBounds == null || outAppBounds.isEmpty()) { + // App-bounds hasn't been overridden, so calculate a value for it. inOutConfig.windowConfiguration.setAppBounds(mTmpFullBounds); outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); - } - // Non-null compatibility insets means the activity prefers to keep its original size, so - // the out bounds doesn't need to be restricted by the parent or current display. - final boolean customContainerPolicy = compatInsets != null; - if (!customContainerPolicy && windowingMode != WINDOWING_MODE_FREEFORM) { - final Rect containingAppBounds; - if (insideParentBounds) { - containingAppBounds = parentConfig.windowConfiguration.getAppBounds(); - } else { - // Restrict appBounds to display non-decor rather than parent because the override - // bounds are beyond the parent. Otherwise, it won't match the overridden bounds. - final TaskDisplayArea displayArea = getDisplayArea(); - containingAppBounds = displayArea != null - ? displayArea.getWindowConfiguration().getAppBounds() : null; - } - if (containingAppBounds != null && !containingAppBounds.isEmpty()) { - outAppBounds.intersect(containingAppBounds); + + if (!customContainerPolicy && windowingMode != WINDOWING_MODE_FREEFORM) { + final Rect containingAppBounds; + if (insideParentBounds) { + containingAppBounds = parentConfig.windowConfiguration.getAppBounds(); + } else { + // Restrict appBounds to display non-decor rather than parent because the + // override bounds are beyond the parent. Otherwise, it won't match the + // overridden bounds. + final TaskDisplayArea displayArea = getDisplayArea(); + containingAppBounds = displayArea != null + ? displayArea.getWindowConfiguration().getAppBounds() : null; + } + if (containingAppBounds != null && !containingAppBounds.isEmpty()) { + outAppBounds.intersect(containingAppBounds); + } } } @@ -2904,7 +2918,7 @@ class Task extends WindowContainer<WindowContainer> { adjustBoundsForDisplayChangeIfNeeded(dc); } super.onDisplayChanged(dc); - if (!isRootTask) { + if (isLeafTask()) { final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY; mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged( mTaskId, displayId); @@ -3112,7 +3126,8 @@ class Task extends WindowContainer<WindowContainer> { @Override boolean showToCurrentUser() { - return mForceShowForAllUsers || showForAllUsers() || mWmService.isCurrentProfile(mUserId); + return mForceShowForAllUsers || showForAllUsers() + || mWmService.isCurrentProfile(getTopMostTask().mUserId); } void setForceShowForAllUsers(boolean forceShowForAllUsers) { @@ -4399,16 +4414,25 @@ class Task extends WindowContainer<WindowContainer> { return mHasBeenVisible; } - /** In the case that these three conditions are true, we want to send the Task to - * the organizer: - * 1. We have a SurfaceControl - * 2. An organizer has been set - * 3. We have finished drawing + /** In the case that these conditions are true, we want to send the Task to the organizer: + * 1. An organizer has been set + * 2. The Task was created by the organizer + * or + * 2a. We have a SurfaceControl + * 2b. We have finished drawing * Any time any of these conditions are updated, the updating code should call * sendTaskAppeared. */ boolean taskAppearedReady() { - return mSurfaceControl != null && mTaskOrganizer != null && getHasBeenVisible(); + if (mTaskOrganizer == null) { + return false; + } + + if (mCreatedByOrganizer) { + return true; + } + + return mSurfaceControl != null && getHasBeenVisible(); } private void sendTaskAppeared() { @@ -4417,9 +4441,9 @@ class Task extends WindowContainer<WindowContainer> { } } - private void sendTaskVanished() { - if (mTaskOrganizer != null) { - mAtmService.mTaskOrganizerController.onTaskVanished(mTaskOrganizer, this); + private void sendTaskVanished(ITaskOrganizer organizer) { + if (organizer != null) { + mAtmService.mTaskOrganizerController.onTaskVanished(organizer, this); } } @@ -4428,9 +4452,13 @@ class Task extends WindowContainer<WindowContainer> { if (mTaskOrganizer == organizer) { return false; } - // Let the old organizer know it has lost control. - sendTaskVanished(); + + ITaskOrganizer previousOrganizer = mTaskOrganizer; + // Update the new task organizer before calling sendTaskVanished since it could result in + // a new SurfaceControl getting created that would notify the old organizer about it. mTaskOrganizer = organizer; + // Let the old organizer know it has lost control. + sendTaskVanished(previousOrganizer); if (mTaskOrganizer != null) { sendTaskAppeared(); diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java index e4f10d9840b2..4b0e293e831e 100644 --- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java +++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java @@ -123,7 +123,7 @@ class TaskChangeNotificationController { private final TaskStackConsumer mNotifyActivityRestartAttempt = (l, m) -> { SomeArgs args = (SomeArgs) m.obj; l.onActivityRestartAttempt((RunningTaskInfo) args.arg1, args.argi1 != 0, - args.argi2 != 0); + args.argi2 != 0, args.argi3 != 0); }; private final TaskStackConsumer mNotifyActivityForcedResizable = (l, m) -> { @@ -368,12 +368,13 @@ class TaskChangeNotificationController { * running, but the task is either brought to the front or a new Intent is delivered to it. */ void notifyActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask) { + boolean clearedTask, boolean wasVisible) { mHandler.removeMessages(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG); final SomeArgs args = SomeArgs.obtain(); args.arg1 = task; args.argi1 = homeTaskVisible ? 1 : 0; args.argi2 = clearedTask ? 1 : 0; + args.argi3 = wasVisible ? 1 : 0; final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG, args); forAllLocalListeners(mNotifyActivityRestartAttempt, msg); diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 306c100e651c..83105c2f8696 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -36,6 +36,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; import android.util.SparseArray; +import android.view.SurfaceControl; import android.window.ITaskOrganizer; import android.window.ITaskOrganizerController; import android.window.WindowContainerToken; @@ -112,7 +113,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { final RunningTaskInfo taskInfo = task.getTaskInfo(); mDeferTaskOrgCallbacksConsumer.accept(() -> { try { - mTaskOrganizer.onTaskAppeared(taskInfo); + SurfaceControl outSurfaceControl = new SurfaceControl(task.getSurfaceControl()); + mTaskOrganizer.onTaskAppeared(taskInfo, outSurfaceControl); } catch (RemoteException e) { Slog.e(TAG, "Exception sending onTaskAppeared callback", e); } @@ -211,6 +213,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void removeTask(Task t) { if (t.mTaskAppearedSent) { + t.migrateToNewSurfaceControl(); t.mTaskAppearedSent = false; mOrganizer.onTaskVanished(t); } diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index be0d6f8a0b9f..c68b660bb76f 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -53,7 +53,6 @@ import android.view.InputDevice; import android.view.InputEvent; import android.view.InputWindowHandle; import android.view.MotionEvent; -import android.view.SurfaceControl; import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; @@ -268,9 +267,7 @@ class TaskPositioner implements IBinder.DeathRecipient { mDisplayContent.getDisplayRotation().pause(); // Notify InputMonitor to take mDragWindowHandle. - final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); - mDisplayContent.getInputMonitor().updateInputWindowsImmediately(t); - t.syncInputWindows().apply(); + mService.mTaskPositioningController.showInputSurface(win.getDisplayId()); final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics(); mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics); @@ -301,6 +298,7 @@ class TaskPositioner implements IBinder.DeathRecipient { return; } + mService.mTaskPositioningController.hideInputSurface(mDisplayContent.getDisplayId()); mService.mInputManager.unregisterInputChannel(mServerChannel); mInputEventReceiver.dispose(); diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java index 2d303faa7921..d343daf46f13 100644 --- a/services/core/java/com/android/server/wm/TaskPositioningController.java +++ b/services/core/java/com/android/server/wm/TaskPositioningController.java @@ -55,6 +55,8 @@ class TaskPositioningController { return mTaskPositioner != null; } + final SurfaceControl.Transaction mTransaction; + InputWindowHandle getDragWindowHandleLocked() { return mTaskPositioner != null ? mTaskPositioner.mDragWindowHandle : null; } @@ -65,16 +67,18 @@ class TaskPositioningController { mInputManager = inputManager; mActivityManager = activityManager; mHandler = new Handler(looper); + mTransaction = service.mTransactionFactory.get(); } - void hideInputSurface(SurfaceControl.Transaction t, int displayId) { + void hideInputSurface(int displayId) { if (mPositioningDisplay != null && mPositioningDisplay.getDisplayId() == displayId && mInputSurface != null) { - t.hide(mInputSurface); + mTransaction.hide(mInputSurface); + mTransaction.syncInputWindows().apply(); } } - void showInputSurface(SurfaceControl.Transaction t, int displayId) { + void showInputSurface(int displayId) { if (mPositioningDisplay == null || mPositioningDisplay.getDisplayId() != displayId) { return; } @@ -92,16 +96,17 @@ class TaskPositioningController { return; } - t.show(mInputSurface); - t.setInputWindowInfo(mInputSurface, h); - t.setLayer(mInputSurface, Integer.MAX_VALUE); + mTransaction.show(mInputSurface); + mTransaction.setInputWindowInfo(mInputSurface, h); + mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE); final Display display = dc.getDisplay(); final Point p = new Point(); display.getRealSize(p); mTmpClipRect.set(0, 0, p.x, p.y); - t.setWindowCrop(mInputSurface, mTmpClipRect); + mTransaction.setWindowCrop(mInputSurface, mTmpClipRect); + mTransaction.syncInputWindows().apply(); } boolean startMovingTask(IWindow window, float startX, float startY) { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 07cf4e5c1e80..3f8d7b5710aa 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -406,6 +406,40 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } /** + * Create a new SurfaceControl for this WindowContainer and migrate all properties to the new + * SurfaceControl. Properties include: + * 1. Children + * 2. Position + * 3. Z order + * + * Remove the old SurfaceControl since it's no longer needed. + * + * This is used to revoke control of the SurfaceControl from a client process that was + * previously organizing this WindowContainer. + */ + void migrateToNewSurfaceControl() { + SurfaceControl.Transaction t = getPendingTransaction(); + t.remove(mSurfaceControl); + // Clear the last position so the new SurfaceControl will get correct position + mLastSurfacePosition.set(0, 0); + + createSurfaceControl(false /* force */); + if (mLastRelativeToLayer != null) { + t.setRelativeLayer(mSurfaceControl, mLastRelativeToLayer, mLastLayer); + } else { + t.setLayer(mSurfaceControl, mLastLayer); + } + + for (int i = 0; i < mChildren.size(); i++) { + SurfaceControl sc = mChildren.get(i).getSurfaceControl(); + if (sc != null) { + t.reparent(sc, mSurfaceControl); + } + } + scheduleAnimation(); + } + + /** * Called when the surface is shown for the first time. */ void onSurfaceShown(Transaction t) { @@ -2523,16 +2557,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return (RemoteToken) binder; } - @Override - public SurfaceControl getLeash() { - final WindowContainer wc = getContainer(); - if (wc == null) return null; - // We need to copy the SurfaceControl instead of returning the original - // because the Parcel FLAGS PARCELABLE_WRITE_RETURN_VALUE cause SurfaceControls - // to release themselves. - return new SurfaceControl(wc.getSurfaceControl()); - } - WindowContainerToken toWindowContainerToken() { if (mWindowContainerToken == null) { mWindowContainerToken = new WindowContainerToken(this); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4eba8b0b55b4..9c0822e63c5a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -402,12 +402,18 @@ public class WindowManagerService extends IWindowManager.Stub private static final String HIERARCHICAL_ANIMATIONS_PROPERTY = "persist.wm.hierarchical_animations"; + private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY = + "ro.sf.disable_triple_buffer"; + /** * @see #HIERARCHICAL_ANIMATIONS_PROPERTY */ static boolean sHierarchicalAnimations = SystemProperties.getBoolean(HIERARCHICAL_ANIMATIONS_PROPERTY, true); + static boolean sEnableTripleBuffering = !SystemProperties.getBoolean( + DISABLE_TRIPLE_BUFFERING_PROPERTY, false); + // Enums for animation scale update types. @Retention(RetentionPolicy.SOURCE) @IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE}) @@ -1607,6 +1613,14 @@ public class WindowManagerService extends IWindowManager.Stub // From now on, no exceptions or errors allowed! res = WindowManagerGlobal.ADD_OKAY; + + if (mUseBLAST) { + res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST; + } + if (sEnableTripleBuffering) { + res |= WindowManagerGlobal.ADD_FLAG_USE_TRIPLE_BUFFERING; + } + if (displayContent.mCurrentFocus == null) { displayContent.mWinAddedSinceNullFocus.add(win); } @@ -3900,6 +3914,30 @@ public class WindowManagerService extends IWindowManager.Stub } @Override + public void setShellRootAccessibilityWindow(int displayId, int windowType, IWindow target) { + if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS); + } + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final DisplayContent dc = mRoot.getDisplayContent(displayId); + if (dc == null) { + return; + } + ShellRoot root = dc.mShellRoots.get(windowType); + if (root == null) { + return; + } + root.setAccessibilityWindow(target); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override public void setDisplayWindowInsetsController( int displayId, IDisplayWindowInsetsController insetsController) { if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS) diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 1784e2186aa5..c4cb4b5091d8 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; +import static android.Manifest.permission.READ_FRAME_BUFFER; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED; @@ -27,17 +28,20 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP; import android.app.WindowConfiguration; import android.content.pm.ActivityInfo; import android.content.res.Configuration; +import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.ArraySet; import android.util.Slog; +import android.view.Surface; import android.view.SurfaceControl; import android.window.IDisplayAreaOrganizerController; import android.window.ITaskOrganizerController; import android.window.IWindowContainerTransactionCallback; import android.window.IWindowOrganizerController; +import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import com.android.internal.util.function.pooled.PooledConsumer; @@ -377,6 +381,40 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mTransactionCallbacksByPendingSyncId.remove(mSyncId); } + @Override + public boolean takeScreenshot(WindowContainerToken token, SurfaceControl outSurfaceControl) { + mService.mAmInternal.enforceCallingPermission(READ_FRAME_BUFFER, "takeScreenshot()"); + final WindowContainer wc = WindowContainer.fromBinder(token.asBinder()); + if (wc == null) { + throw new RuntimeException("Invalid token in screenshot transaction"); + } + + final Rect bounds = new Rect(); + wc.getBounds(bounds); + bounds.offsetTo(0, 0); + SurfaceControl.ScreenshotGraphicBuffer buffer = SurfaceControl.captureLayers( + wc.getSurfaceControl(), bounds, 1); + + if (buffer == null || buffer.getGraphicBuffer() == null) { + return false; + } + + SurfaceControl screenshot = mService.mWindowManager.mSurfaceControlFactory.apply(null) + .setName(wc.getName() + " - Organizer Screenshot") + .setBufferSize(bounds.width(), bounds.height()) + .setFormat(PixelFormat.TRANSLUCENT) + .setParent(wc.getParentSurfaceControl()) + .build(); + + Surface surface = new Surface(); + surface.copyFrom(screenshot); + surface.attachAndQueueBufferWithColorSpace(buffer.getGraphicBuffer(), null); + surface.release(); + + outSurfaceControl.copyFrom(screenshot); + return true; + } + private void enforceStackPermission(String func) { mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func); } diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 41bd70726e71..fe68cd6110f2 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -29,6 +29,7 @@ import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStack.ActivityState.STARTED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; @@ -430,6 +431,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio void setLastActivityLaunchTime(long launchTime) { if (launchTime <= mLastActivityLaunchTime) { + if (launchTime < mLastActivityLaunchTime) { + Slog.w(TAG, + "Tried to set launchTime (" + launchTime + ") < mLastActivityLaunchTime (" + + mLastActivityLaunchTime + ")"); + } return; } mLastActivityLaunchTime = launchTime; @@ -449,6 +455,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio boolean areBackgroundActivityStartsAllowed() { // allow if the whitelisting flag was explicitly set if (mAllowBackgroundActivityStarts) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "[WindowProcessController(" + mPid + + ")] Activity start allowed: mAllowBackgroundActivityStarts = true"); + } return true; } // allow if any activity in the caller has either started or finished very recently, and @@ -460,19 +470,43 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // let app to be able to start background activity even it's in grace period. if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime() || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "[WindowProcessController(" + mPid + + ")] Activity start allowed: within " + + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period"); + } return true; } + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within " + + ACTIVITY_BG_START_GRACE_PERIOD_MS + + "ms grace period but also within stop app switch window"); + } + } // allow if the proc is instrumenting with background activity starts privs if (mInstrumentingWithBackgroundActivityStartPrivileges) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "[WindowProcessController(" + mPid + + ")] Activity start allowed: process instrumenting with background " + + "activity starts privileges"); + } return true; } // allow if the caller has an activity in any foreground task if (hasActivityInVisibleTask()) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "[WindowProcessController(" + mPid + + ")] Activity start allowed: process has activity in foreground task"); + } return true; } // allow if the caller is bound by a UID that's currently foreground if (isBoundByForegroundUid()) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "[WindowProcessController(" + mPid + + ")] Activity start allowed: process bound by foreground uid"); + } return true; } return false; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 706dcba31cfe..f6473fd8acd1 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2491,6 +2491,23 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } /** + * Expands the given rectangle by the region of window resize handle for freeform window. + * @param inOutRect The rectangle to update. + */ + private void adjustRegionInFreefromWindowMode(Rect inOutRect) { + if (!inFreeformWindowingMode()) { + return; + } + + // For freeform windows, we need the touch region to include the whole + // surface for the shadows. + final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); + final int delta = WindowManagerService.dipToPixel( + RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); + inOutRect.inset(-delta, -delta); + } + + /** * Updates the region for a window in an Activity that was a touch modal. This will limit * the outer touch to the activity stack region. * @param outRegion The region to update. @@ -2513,14 +2530,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP getRootTask().getDimBounds(mTmpRect); } } - if (inFreeformWindowingMode()) { - // For freeform windows, we need the touch region to include the whole - // surface for the shadows. - final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); - final int delta = WindowManagerService.dipToPixel( - RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); - mTmpRect.inset(-delta, -delta); - } + adjustRegionInFreefromWindowMode(mTmpRect); outRegion.set(mTmpRect); cropRegionToStackBoundsIfNeeded(outRegion); } @@ -3335,7 +3345,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } final ActivityStack stack = task.getStack(); - if (stack == null) { + if (stack == null || inFreeformWindowingMode()) { + handle.setTouchableRegionCrop(null); return; } @@ -3354,6 +3365,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } stack.getDimBounds(mTmpRect); + adjustRegionInFreefromWindowMode(mTmpRect); region.op(mTmpRect, Region.Op.INTERSECT); } @@ -5595,7 +5607,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) { - final float fraction = (float) currentPlayTime / getDuration(); + final float fraction = getFraction(currentPlayTime); final float v = mInterpolator.getInterpolation(fraction); t.setPosition(leash, mFrom.x + (mTo.x - mFrom.x) * v, mFrom.y + (mTo.y - mFrom.y) * v); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index bfe3b2890bc1..0e83beed6b90 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -57,6 +57,7 @@ import static com.android.server.wm.WindowStateAnimatorProto.SURFACE; import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; +import android.app.WindowConfiguration; import android.content.Context; import android.graphics.Matrix; import android.graphics.PixelFormat; @@ -787,7 +788,8 @@ class WindowStateAnimator { return false; } - if (w.getWindowConfiguration().tasksAreFloating()) { + if (w.getWindowConfiguration().tasksAreFloating() + || WindowConfiguration.isSplitScreenWindowingMode(w.getWindowingMode())) { return false; } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 55e6ab76188d..0a7ca5a0cf35 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -115,8 +115,8 @@ class WindowSurfaceController { .setMetadata(METADATA_WINDOW_TYPE, windowType) .setMetadata(METADATA_OWNER_UID, ownerUid); - final boolean useBLAST = (win.getAttrs().privateFlags & - WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0; + final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags & + WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0); if (useBLAST) { b.setContainerLayer(); } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 21c76874f5c0..472773e1bb1a 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -119,7 +119,6 @@ class WindowToken extends WindowContainer<WindowState> { * rotated by the given rotated display info, frames and insets. */ private static class FixedRotationTransformState { - final WindowToken mOwner; final DisplayInfo mDisplayInfo; final DisplayFrames mDisplayFrames; final InsetsState mInsetsState; @@ -133,10 +132,9 @@ class WindowToken extends WindowContainer<WindowState> { final ArrayList<WindowContainer<?>> mRotatedContainers = new ArrayList<>(3); boolean mIsTransforming = true; - FixedRotationTransformState(WindowToken owner, DisplayInfo rotatedDisplayInfo, + FixedRotationTransformState(DisplayInfo rotatedDisplayInfo, DisplayFrames rotatedDisplayFrames, InsetsState rotatedInsetsState, Configuration rotatedConfig, int currentRotation) { - mOwner = owner; mDisplayInfo = rotatedDisplayInfo; mDisplayFrames = rotatedDisplayFrames; mInsetsState = rotatedInsetsState; @@ -482,6 +480,14 @@ class WindowToken extends WindowContainer<WindowState> { return mFixedRotationTransformState != null; } + /** Returns {@code true} if the given token shares the same transform. */ + boolean hasFixedRotationTransform(WindowToken token) { + if (mFixedRotationTransformState == null || token == null) { + return false; + } + return this == token || mFixedRotationTransformState == token.mFixedRotationTransformState; + } + boolean isFinishingFixedRotationTransform() { return mFixedRotationTransformState != null && !mFixedRotationTransformState.mIsTransforming; @@ -520,15 +526,14 @@ class WindowToken extends WindowContainer<WindowState> { final InsetsState insetsState = new InsetsState(); mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames, insetsState, mDisplayContent.getConfiguration().uiMode); - mFixedRotationTransformState = new FixedRotationTransformState(this, info, displayFrames, + mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames, insetsState, new Configuration(config), mDisplayContent.getRotation()); onConfigurationChanged(getParent().getConfiguration()); } /** * Reuses the {@link FixedRotationTransformState} (if any) from the other WindowToken to this - * one. This takes the same effect as {@link #applyFixedRotationTransform}, but the linked state - * can only be cleared by the state owner. + * one. This takes the same effect as {@link #applyFixedRotationTransform}. */ void linkFixedRotationTransform(WindowToken other) { if (mFixedRotationTransformState != null) { @@ -543,28 +548,15 @@ class WindowToken extends WindowContainer<WindowState> { onConfigurationChanged(getParent().getConfiguration()); } - /** - * Finishes the transform and continue updating the orientation change of display. Only the - * state owner can finish the transform state. - */ void finishFixedRotationTransform() { - if (mFixedRotationTransformState == null || mFixedRotationTransformState.mOwner != this) { - return; - } - final boolean changed = - mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(this); - // If it is not the launching app or the display is not rotated, make sure the transform is - // cleared and the configuration is restored from parent. - if (!changed) { - clearFixedRotationTransform(null /* applyDisplayRotation */); - } + finishFixedRotationTransform(null /* applyDisplayRotation */); } /** - * Clears the transform and apply display rotation if the action is given. If the display will + * Finishes the transform and apply display rotation if the action is given. If the display will * not rotate, the transformed containers are restored to their original states. */ - void clearFixedRotationTransform(Runnable applyDisplayRotation) { + void finishFixedRotationTransform(Runnable applyDisplayRotation) { final FixedRotationTransformState state = mFixedRotationTransformState; if (state == null) { return; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 5d5e424db017..a74706be8915 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7326,13 +7326,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return admin != null ? admin.mFactoryResetProtectionPolicy : null; } - private int getFrpManagementAgentUidOrThrow() { + private int getFrpManagementAgentUid() { PersistentDataBlockManagerInternal pdb = mInjector.getPersistentDataBlockManagerInternal(); - if ((pdb == null) || (pdb.getAllowedUid() == -1)) { + return pdb != null ? pdb.getAllowedUid() : -1; + } + + private int getFrpManagementAgentUidOrThrow() { + int uid = getFrpManagementAgentUid(); + if (uid == -1) { throw new UnsupportedOperationException( "The persistent data block service is not supported on this device"); } - return pdb.getAllowedUid(); + return uid; + } + + @Override + public boolean isFactoryResetProtectionPolicySupported() { + return getFrpManagementAgentUid() != -1; } @Override @@ -15938,22 +15948,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { */ private void updatePersonalAppsSuspension(int profileUserId, boolean unlocked) { final boolean suspended; + final int deadlineState; + final String poPackage; synchronized (getLockObject()) { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId); if (profileOwner != null) { - final int deadlineState = + deadlineState = updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked); suspended = profileOwner.mSuspendPersonalApps || deadlineState == PROFILE_OFF_DEADLINE_REACHED; - Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d", - suspended, deadlineState)); - updateProfileOffDeadlineNotificationLocked(profileUserId, profileOwner, - unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState); + poPackage = profileOwner.info.getPackageName(); } else { + poPackage = null; suspended = false; + deadlineState = PROFILE_OFF_DEADLINE_DEFAULT; } } + Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d", + suspended, deadlineState)); + + if (poPackage != null) { + final int notificationState = unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState; + updateProfileOffDeadlineNotification(profileUserId, poPackage, notificationState); + } + final int parentUserId = getProfileParentId(profileUserId); suspendPersonalAppsInternal(parentUserId, suspended); } @@ -16057,38 +16076,34 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void updateProfileOffDeadlineNotificationLocked(int profileUserId, - @Nullable ActiveAdmin profileOwner, int notificationState) { + private void updateProfileOffDeadlineNotification( + int profileUserId, String profileOwnerPackage, int notificationState) { if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) { mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED); return; } - final String profileOwnerPackageName = profileOwner.info.getPackageName(); - final long maxTimeOffDays = - TimeUnit.MILLISECONDS.toDays(profileOwner.mProfileMaximumTimeOffMillis); - final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE); - intent.setPackage(profileOwnerPackageName); + intent.setPackage(profileOwnerPackage); final PendingIntent pendingIntent = mInjector.pendingIntentGetActivityAsUser(mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT, null /* options */, UserHandle.of(profileUserId)); // TODO(b/149075510): Only the first of the notifications should be dismissible. - final String title = mContext.getString( + final String text = mContext.getString( notificationState == PROFILE_OFF_DEADLINE_WARNING - ? R.string.personal_apps_suspended_tomorrow_title - : R.string.personal_apps_suspended_title); + ? R.string.personal_apps_suspension_tomorrow_text + : R.string.personal_apps_suspension_text); final Notification notification = new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN) .setSmallIcon(android.R.drawable.stat_sys_warning) .setOngoing(true) - .setContentTitle(title) - .setContentText(mContext.getString( - R.string.personal_apps_suspended_text, maxTimeOffDays)) + .setContentTitle(mContext.getString( + R.string.personal_apps_suspension_title)) + .setContentText(text) .setColor(mContext.getColor(R.color.system_notification_accent_color)) .setContentIntent(pendingIntent) .build(); diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index cae5027250e1..992a4ef76f04 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -761,10 +761,7 @@ int IncrementalService::unbind(StorageId storage, std::string_view target) { std::unique_lock l2(ifs->lock); if (ifs->bindPoints.size() <= 1) { ifs->bindPoints.clear(); - std::thread([this, ifs, l2 = std::move(l2)]() mutable { - mJni->initializeForCurrentThread(); - deleteStorageLocked(*ifs, std::move(l2)); - }).detach(); + deleteStorageLocked(*ifs, std::move(l2)); } else { const std::string savedFile = std::move(bindIt->second.savedFilename); ifs->bindPoints.erase(bindIt); @@ -1711,15 +1708,19 @@ bool IncrementalService::DataLoaderStub::setTargetStatus(int newStatus) { { std::unique_lock lock(mStatusMutex); oldStatus = mTargetStatus; - mTargetStatus = newStatus; - mTargetStatusTs = Clock::now(); curStatus = mCurrentStatus; + setTargetStatusLocked(newStatus); } LOG(DEBUG) << "Target status update for DataLoader " << mId << ": " << oldStatus << " -> " << newStatus << " (current " << curStatus << ")"; return fsmStep(); } +void IncrementalService::DataLoaderStub::setTargetStatusLocked(int status) { + mTargetStatus = status; + mTargetStatusTs = Clock::now(); +} + bool IncrementalService::DataLoaderStub::waitForStatus(int status, Clock::duration duration) { auto now = Clock::now(); std::unique_lock lock(mStatusMutex); @@ -1785,6 +1786,9 @@ bool IncrementalService::DataLoaderStub::fsmStep() { } switch (targetStatus) { + case IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE: + // Do nothing, this is a reset state. + break; case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: { return destroy(); } @@ -1799,6 +1803,7 @@ bool IncrementalService::DataLoaderStub::fsmStep() { case IDataLoaderStatusListener::DATA_LOADER_CREATED: switch (currentStatus) { case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: + case IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE: return bind(); case IDataLoaderStatusListener::DATA_LOADER_BOUND: return create(); @@ -1828,9 +1833,15 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount if (mCurrentStatus == newStatus) { return binder::Status::ok(); } + oldStatus = mCurrentStatus; mCurrentStatus = newStatus; targetStatus = mTargetStatus; + + if (mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE) { + // For unavailable, reset target status. + setTargetStatusLocked(IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE); + } } LOG(DEBUG) << "Current status update for DataLoader " << mId << ": " << oldStatus << " -> " diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h index 81fbe74be606..d5c612daee58 100644 --- a/services/incremental/IncrementalService.h +++ b/services/incremental/IncrementalService.h @@ -187,6 +187,7 @@ private: bool destroy(); bool setTargetStatus(int status); + void setTargetStatusLocked(int status); bool waitForStatus(int status, Clock::duration duration); bool fsmStep(); diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java index fea61aa43442..dfe75ed50cd4 100644 --- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java +++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java @@ -30,10 +30,13 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; import static org.testng.Assert.expectThrows; import android.app.backup.BackupManager; @@ -86,6 +89,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -104,6 +108,7 @@ public class UserBackupManagerServiceTest { private static final String TAG = "BMSTest"; private static final String PACKAGE_1 = "some.package.1"; private static final String PACKAGE_2 = "some.package.2"; + private static final String USER_FACING_PACKAGE = "user.facing.package"; private static final int USER_ID = 10; @Mock private TransportManager mTransportManager; @@ -1186,6 +1191,47 @@ public class UserBackupManagerServiceTest { eq(packageTrackingReceiver), eq(UserHandle.of(USER_ID)), any(), any(), any()); } + @Test + public void testFilterUserFacingPackages_shouldSkipUserFacing_filtersUserFacing() { + List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE), + getPackageInfo(PACKAGE_1)); + UserBackupManagerService backupManagerService = spy( + createUserBackupManagerServiceAndRunTasks()); + when(backupManagerService.shouldSkipUserFacingData()).thenReturn(true); + when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true); + + List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages( + packages); + + assertFalse(containsPackage(filteredPackages, USER_FACING_PACKAGE)); + assertTrue(containsPackage(filteredPackages, PACKAGE_1)); + } + + @Test + public void testFilterUserFacingPackages_shouldNotSkipUserFacing_doesNotFilterUserFacing() { + List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE), + getPackageInfo(PACKAGE_1)); + UserBackupManagerService backupManagerService = spy( + createUserBackupManagerServiceAndRunTasks()); + when(backupManagerService.shouldSkipUserFacingData()).thenReturn(false); + when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true); + + List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages( + packages); + + assertTrue(containsPackage(filteredPackages, USER_FACING_PACKAGE)); + assertTrue(containsPackage(filteredPackages, PACKAGE_1)); + } + + private static boolean containsPackage(List<PackageInfo> packages, String targetPackage) { + for (PackageInfo packageInfo : packages) { + if (targetPackage.equals(packageInfo.packageName)) { + return true; + } + } + return false; + } + private UserBackupManagerService createUserBackupManagerServiceAndRunTasks() { return BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks( USER_ID, mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager); diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java index bc0b184cd359..c8ec7b5503d1 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java @@ -620,6 +620,77 @@ public class QuotaControllerTest { assertEquals(expectedStats, inputStats); } + @Test + public void testUpdateExecutionStatsLocked_WithTimer() { + final long now = sElapsedRealtimeClock.millis(); + setProcessState(ActivityManager.PROCESS_STATE_SERVICE); + + ExecutionStats expectedStats = new ExecutionStats(); + ExecutionStats inputStats = new ExecutionStats(); + inputStats.windowSizeMs = expectedStats.windowSizeMs = 24 * HOUR_IN_MILLIS; + inputStats.jobCountLimit = expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_RARE; + inputStats.sessionCountLimit = expectedStats.sessionCountLimit = + mQcConstants.MAX_SESSION_COUNT_RARE; + // Active timer isn't counted as session yet. + expectedStats.sessionCountInWindow = 0; + // Timer only, under quota. + for (int i = 1; i < mQcConstants.MAX_JOB_COUNT_RARE; ++i) { + JobStatus jobStatus = createJobStatus("testUpdateExecutionStatsLocked_WithTimer", i); + setStandbyBucket(RARE_INDEX, jobStatus); // 24 hour window + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + advanceElapsedClock(7000); + + expectedStats.expirationTimeElapsed = sElapsedRealtimeClock.millis(); + expectedStats.executionTimeInWindowMs = expectedStats.executionTimeInMaxPeriodMs = + 7000 * i; + expectedStats.bgJobCountInWindow = expectedStats.bgJobCountInMaxPeriod = i; + mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); + assertEquals(expectedStats, inputStats); + assertTrue(mQuotaController.isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, + RARE_INDEX)); + } + + // Add old session. Make sure values are combined correctly. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(sElapsedRealtimeClock.millis() - (6 * HOUR_IN_MILLIS), + 10 * MINUTE_IN_MILLIS, 5)); + expectedStats.sessionCountInWindow = 1; + + expectedStats.expirationTimeElapsed = sElapsedRealtimeClock.millis() + 18 * HOUR_IN_MILLIS; + expectedStats.executionTimeInWindowMs += 10 * MINUTE_IN_MILLIS; + expectedStats.executionTimeInMaxPeriodMs += 10 * MINUTE_IN_MILLIS; + expectedStats.bgJobCountInWindow += 5; + expectedStats.bgJobCountInMaxPeriod += 5; + // Active timer is under quota, so out of quota due to old session. + expectedStats.inQuotaTimeElapsed = + sElapsedRealtimeClock.millis() + 18 * HOUR_IN_MILLIS + 10 * MINUTE_IN_MILLIS; + mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); + assertEquals(expectedStats, inputStats); + assertFalse( + mQuotaController.isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); + + // Quota should be exceeded due to activity in active timer. + JobStatus jobStatus = createJobStatus("testUpdateExecutionStatsLocked_WithTimer", 0); + setStandbyBucket(RARE_INDEX, jobStatus); // 24 hour window + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + advanceElapsedClock(10000); + + expectedStats.executionTimeInWindowMs += 10000; + expectedStats.executionTimeInMaxPeriodMs += 10000; + expectedStats.bgJobCountInWindow++; + expectedStats.bgJobCountInMaxPeriod++; + // Out of quota due to activity in active timer, so in quota time should be when enough + // time has passed since active timer. + expectedStats.inQuotaTimeElapsed = + sElapsedRealtimeClock.millis() + expectedStats.windowSizeMs; + mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); + assertEquals(expectedStats, inputStats); + assertFalse( + mQuotaController.isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); + } + /** * Tests that getExecutionStatsLocked returns the correct stats. */ diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index b457856e8630..40a17061c7f1 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -99,6 +99,7 @@ android_test { ":PackageParserTestApp1", ":PackageParserTestApp2", ":PackageParserTestApp3", + ":apex.test", ], resource_zips: [":FrameworksServicesTests_apks_as_resources"], } diff --git a/services/tests/servicestests/res/raw/apex_test.apex b/services/tests/servicestests/res/raw/apex_test.apex Binary files differdeleted file mode 100644 index 19b1c5e2e1c6..000000000000 --- a/services/tests/servicestests/res/raw/apex_test.apex +++ /dev/null diff --git a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java index 064e3486823a..98f476464842 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java @@ -67,7 +67,7 @@ import java.util.concurrent.TimeUnit; */ public class SystemActionPerformerTest { private static final int LATCH_TIMEOUT_MS = 500; - private static final int LEGACY_SYSTEM_ACTION_COUNT = 9; + private static final int LEGACY_SYSTEM_ACTION_COUNT = 8; private static final int NEW_ACTION_ID = 20; private static final String LABEL_1 = "label1"; private static final String LABEL_2 = "label2"; 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 b042e7794666..c2285081770e 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -15,6 +15,8 @@ */ package com.android.server.devicepolicy; +import static android.app.Notification.EXTRA_TEXT; +import static android.app.Notification.EXTRA_TITLE; import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS; import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL; import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO; @@ -195,9 +197,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { PROFILE_OFF_START + PROFILE_OFF_TIMEOUT - TimeUnit.DAYS.toMillis(1); // Time when the apps should be suspended private static final long PROFILE_OFF_DEADLINE = PROFILE_OFF_START + PROFILE_OFF_TIMEOUT; - // Notification titles for setManagedProfileMaximumTimeOff tests: - private static final String PROFILE_OFF_WARNING_TITLE = "suspended_tomorrow"; - private static final String PROFILE_OFF_SUSPENDED_TITLE = "suspended"; + // Notification title and text for setManagedProfileMaximumTimeOff tests: + private static final String PROFILE_OFF_SUSPENSION_TITLE = "suspension_title"; + private static final String PROFILE_OFF_SUSPENSION_TEXT = "suspension_text"; + private static final String PROFILE_OFF_SUSPENSION_TOMORROW_TEXT = "suspension_tomorrow_text"; @Override protected void setUp() throws Exception { @@ -1576,7 +1579,9 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpms.approveCaCert(fourCerts.getList().get(1), userId, true); // a notification should be shown saying that there are two certificates left to approve. verify(getServices().notificationManager, timeout(1000)) - .notifyAsUser(anyString(), anyInt(), argThat(hasTitle(TEST_STRING)), eq(user)); + .notifyAsUser(anyString(), anyInt(), argThat(hasExtra(EXTRA_TITLE, + TEST_STRING + )), eq(user)); } /** @@ -6317,7 +6322,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().alarmManager, times(1)).set(anyInt(), eq(PROFILE_OFF_DEADLINE), any()); // Now the user should see a warning notification. verify(getServices().notificationManager, times(1)) - .notify(anyInt(), argThat(hasTitle(PROFILE_OFF_WARNING_TITLE))); + .notify(anyInt(), argThat(hasExtra(EXTRA_TITLE, PROFILE_OFF_SUSPENSION_TITLE, + EXTRA_TEXT, PROFILE_OFF_SUSPENSION_TOMORROW_TEXT))); // Apps shouldn't be suspended yet. verifyZeroInteractions(getServices().ipackageManager); clearInvocations(getServices().alarmManager); @@ -6331,7 +6337,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { verifyZeroInteractions(getServices().alarmManager); // Now the user should see a notification about suspended apps. verify(getServices().notificationManager, times(1)) - .notify(anyInt(), argThat(hasTitle(PROFILE_OFF_SUSPENDED_TITLE))); + .notify(anyInt(), argThat(hasExtra(EXTRA_TITLE, PROFILE_OFF_SUSPENSION_TITLE, + EXTRA_TEXT, PROFILE_OFF_SUSPENSION_TEXT))); // Verify that the apps are suspended. verify(getServices().ipackageManager, times(1)).setPackagesSuspendedAsUser( any(), eq(true), any(), any(), any(), any(), anyInt()); @@ -6461,25 +6468,41 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Setup notification titles. when(mServiceContext.resources - .getString(R.string.personal_apps_suspended_tomorrow_title)) - .thenReturn(PROFILE_OFF_WARNING_TITLE); + .getString(R.string.personal_apps_suspension_title)) + .thenReturn(PROFILE_OFF_SUSPENSION_TITLE); when(mServiceContext.resources - .getString(R.string.personal_apps_suspended_title)) - .thenReturn(PROFILE_OFF_SUSPENDED_TITLE); + .getString(R.string.personal_apps_suspension_text)) + .thenReturn(PROFILE_OFF_SUSPENSION_TEXT); + when(mServiceContext.resources + .getString(R.string.personal_apps_suspension_tomorrow_text)) + .thenReturn(PROFILE_OFF_SUSPENSION_TOMORROW_TEXT); clearInvocations(getServices().ipackageManager); } - private static Matcher<Notification> hasTitle(String expected) { + private static Matcher<Notification> hasExtra(String... extras) { + assertEquals("Odd numebr of extra key-values", 0, extras.length % 2); return new BaseMatcher<Notification>() { @Override public boolean matches(Object item) { final Notification notification = (Notification) item; - return expected.equals(notification.extras.getString(Notification.EXTRA_TITLE)); + for (int i = 0; i < extras.length / 2; i++) { + if (!extras[i * 2 + 1].equals(notification.extras.getString(extras[i * 2]))) { + return false; + } + } + return true; } @Override public void describeTo(Description description) { - description.appendText("Notification{title=\"" + expected + "\"}"); + description.appendText("Notification{"); + for (int i = 0; i < extras.length / 2; i++) { + if (i > 0) { + description.appendText(","); + } + description.appendText(extras[i * 2] + "=\"" + extras[i * 2 + 1] + "\""); + } + description.appendText("}"); } }; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java index a587029914a7..28887fdab00d 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java @@ -24,6 +24,7 @@ import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2; import static com.android.server.hdmi.Constants.ADDR_TUNER_1; import static com.android.server.hdmi.Constants.ADDR_TV; +import static com.android.server.hdmi.Constants.MESSAGE_GIVE_AUDIO_STATUS; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF; @@ -47,6 +48,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.ArrayList; + @SmallTest @RunWith(JUnit4.class) /** Tests for {@link HdmiCecLocalDeviceAudioSystem} class. */ @@ -167,6 +169,8 @@ public class HdmiCecLocalDeviceAudioSystemTest { } }; + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + mMyLooper = mTestLooper.getLooper(); mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService); mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) { @@ -717,4 +721,112 @@ public class HdmiCecLocalDeviceAudioSystemTest { mHdmiCecLocalDeviceAudioSystem.onHotplug(0, false); assertThat(mWokenUp).isFalse(); } + + @Test + public void giveAudioStatus_volumeEnabled() { + mMusicVolume = 50; + mMusicMaxVolume = 100; + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true); + + int volume = mHdmiControlService.getAudioManager() + .getStreamVolume(AudioManager.STREAM_MUSIC); + boolean mute = mHdmiControlService.getAudioManager() + .isStreamMute(AudioManager.STREAM_MUSIC); + int maxVolume = mHdmiControlService.getAudioManager() + .getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume); + HdmiCecMessage expected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM, + ADDR_TV, scaledVolume, mute); + HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( + ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED); + + HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV, + ADDR_AUDIO_SYSTEM); + mNativeWrapper.clearResultMessages(); + boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus); + mTestLooper.dispatchAll(); + + assertThat(mNativeWrapper.getResultMessages()).contains(expected); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort); + assertThat(handled).isTrue(); + } + + @Test + public void giveAudioStatus_volumeDisabled() { + mMusicVolume = 50; + mMusicMaxVolume = 100; + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true); + + int volume = mHdmiControlService.getAudioManager() + .getStreamVolume(AudioManager.STREAM_MUSIC); + boolean mute = mHdmiControlService.getAudioManager() + .isStreamMute(AudioManager.STREAM_MUSIC); + int maxVolume = mHdmiControlService.getAudioManager() + .getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume); + HdmiCecMessage unexpected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM, + ADDR_TV, scaledVolume, mute); + HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( + ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED); + + HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV, + ADDR_AUDIO_SYSTEM); + mNativeWrapper.clearResultMessages(); + boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus); + mTestLooper.dispatchAll(); + + assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected); + assertThat(handled).isTrue(); + } + + @Test + public void reportAudioStatus_volumeEnabled() { + mMusicVolume = 50; + mMusicMaxVolume = 100; + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true); + + int volume = mHdmiControlService.getAudioManager() + .getStreamVolume(AudioManager.STREAM_MUSIC); + boolean mute = mHdmiControlService.getAudioManager() + .isStreamMute(AudioManager.STREAM_MUSIC); + int maxVolume = mHdmiControlService.getAudioManager() + .getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume); + HdmiCecMessage expected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM, + ADDR_TV, scaledVolume, mute); + + mNativeWrapper.clearResultMessages(); + mHdmiCecLocalDeviceAudioSystem.reportAudioStatus(ADDR_TV); + mTestLooper.dispatchAll(); + + assertThat(mNativeWrapper.getResultMessages()).contains(expected); + } + + @Test + public void reportAudioStatus_volumeDisabled() { + mMusicVolume = 50; + mMusicMaxVolume = 100; + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true); + + int volume = mHdmiControlService.getAudioManager() + .getStreamVolume(AudioManager.STREAM_MUSIC); + boolean mute = mHdmiControlService.getAudioManager() + .isStreamMute(AudioManager.STREAM_MUSIC); + int maxVolume = mHdmiControlService.getAudioManager() + .getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume); + HdmiCecMessage unexpected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM, + ADDR_TV, scaledVolume, mute); + + mNativeWrapper.clearResultMessages(); + mHdmiCecLocalDeviceAudioSystem.reportAudioStatus(ADDR_TV); + mTestLooper.dispatchAll(); + + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected); + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java index f72d622c00c3..b76211895ab0 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -20,8 +20,14 @@ import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC import static com.google.common.truth.Truth.assertThat; +import android.content.Context; +import android.os.Handler; +import android.os.IPowerManager; +import android.os.IThermalService; import android.os.Looper; +import android.os.PowerManager; import android.os.test.TestLooper; +import android.view.KeyEvent; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -31,6 +37,8 @@ import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.util.ArrayList; @@ -49,8 +57,17 @@ public class HdmiCecLocalDevicePlaybackTest { private int mPlaybackPhysicalAddress; private boolean mWokenUp; + @Mock private IPowerManager mIPowerManagerMock; + @Mock private IThermalService mIThermalServiceMock; + @Before public void setUp() { + MockitoAnnotations.initMocks(this); + + Context context = InstrumentationRegistry.getTargetContext(); + mMyLooper = mTestLooper.getLooper(); + PowerManager powerManager = new PowerManager(context, mIPowerManagerMock, + mIThermalServiceMock, new Handler(mMyLooper)); mHdmiControlService = new HdmiControlService(InstrumentationRegistry.getTargetContext()) { @Override @@ -67,9 +84,13 @@ public class HdmiCecLocalDevicePlaybackTest { void writeStringSystemProperty(String key, String value) { // do nothing } + + @Override + PowerManager getPowerManager() { + return powerManager; + } }; - mMyLooper = mTestLooper.getLooper(); mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService); mHdmiCecLocalDevicePlayback.init(); mHdmiControlService.setIoLooper(mMyLooper); @@ -139,7 +160,6 @@ public class HdmiCecLocalDevicePlaybackTest { } @Test - @Ignore("b/151147315") public void doNotWakeUpOnHotPlug_PlugIn() { mWokenUp = false; mHdmiCecLocalDevicePlayback.onHotplug(0, true); @@ -147,10 +167,74 @@ public class HdmiCecLocalDevicePlaybackTest { } @Test - @Ignore("b/151147315") public void doNotWakeUpOnHotPlug_PlugOut() { mWokenUp = false; mHdmiCecLocalDevicePlayback.onHotplug(0, false); assertThat(mWokenUp).isFalse(); } + + @Test + public void sendVolumeKeyEvent_up_volumeEnabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false); + + assertThat(hasSendKeyAction()).isTrue(); + } + + @Test + public void sendVolumeKeyEvent_down_volumeEnabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false); + + assertThat(hasSendKeyAction()).isTrue(); + } + + @Test + public void sendVolumeKeyEvent_mute_volumeEnabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false); + + assertThat(hasSendKeyAction()).isTrue(); + } + + @Test + public void sendVolumeKeyEvent_up_volumeDisabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false); + + assertThat(hasSendKeyAction()).isFalse(); + } + + @Test + public void sendVolumeKeyEvent_down_volumeDisabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false); + + assertThat(hasSendKeyAction()).isFalse(); + } + + @Test + public void sendVolumeKeyEvent_mute_volumeDisabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false); + + assertThat(hasSendKeyAction()).isFalse(); + } + + private boolean hasSendKeyAction() { + boolean match = false; + for (HdmiCecFeatureAction action : mHdmiCecLocalDevicePlayback.mActions) { + if (action instanceof SendKeyAction) { + match = true; + break; + } + } + return match; + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java index 039b90429395..e0bada3138e0 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java @@ -19,6 +19,7 @@ import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV; import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; import static com.android.server.hdmi.Constants.ADDR_BROADCAST; +import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED; import static com.android.server.hdmi.Constants.MESSAGE_DEVICE_VENDOR_ID; @@ -185,4 +186,64 @@ public class HdmiCecLocalDeviceTest { HdmiCecMessageBuilder.buildStandby(ADDR_TV, ADDR_AUDIO_SYSTEM)); assertTrue(mStandbyMessageReceived); } + + @Test + public void handleUserControlPressed_volumeUp() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + boolean result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV, + HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP)); + + assertTrue(result); + } + + @Test + public void handleUserControlPressed_volumeDown() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + boolean result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV, + HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN)); + + assertTrue(result); + } + + @Test + public void handleUserControlPressed_volumeMute() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + boolean result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV, + HdmiCecKeycode.CEC_KEYCODE_MUTE)); + + assertTrue(result); + } + + @Test + public void handleUserControlPressed_volumeUp_disabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + boolean result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV, + HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP)); + + assertFalse(result); + } + + @Test + public void handleUserControlPressed_volumeDown_disabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + boolean result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV, + HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN)); + + assertFalse(result); + } + + @Test + public void handleUserControlPressed_volumeMute_disabled() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + boolean result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV, + HdmiCecKeycode.CEC_KEYCODE_MUTE)); + + assertFalse(result); + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java index fa19814f401f..7af7a23b1ef6 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -252,4 +252,13 @@ public class HdmiControlServiceTest { assertThat(mHdmiControlService.getPowerStatus()).isEqualTo( HdmiControlManager.POWER_STATUS_STANDBY); } + + @Test + public void setAndGetCecVolumeControlEnabled_isApi() { + mHdmiControlService.setHdmiCecVolumeControlEnabled(false); + assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isFalse(); + + mHdmiControlService.setHdmiCecVolumeControlEnabled(true); + assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isTrue(); + } } diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java index 3718c5c5a5e1..72afca0300cd 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java @@ -36,7 +36,6 @@ import android.apex.ApexSessionParams; import android.apex.IApexService; import android.content.Context; import android.content.pm.PackageInfo; -import android.os.FileUtils; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; @@ -44,7 +43,6 @@ import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; -import com.android.frameworks.servicestests.R; import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.TestPackageParser2; @@ -52,11 +50,12 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.io.BufferedOutputStream; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; @SmallTest @Presubmit @@ -64,6 +63,7 @@ import java.io.InputStream; public class ApexManagerTest { private static final String TEST_APEX_PKG = "com.android.apex.test"; + private static final String TEST_APEX_FILE_NAME = "apex.test.apex"; private static final int TEST_SESSION_ID = 99999999; private static final int[] TEST_CHILD_SESSION_ID = {8888, 7777}; private ApexManager mApexManager; @@ -273,14 +273,30 @@ public class ApexManagerTest { assertThat(mApexManager.uninstallApex(TEST_APEX_PKG)).isFalse(); } + @Test + public void testReportErrorWithApkInApex() throws RemoteException { + when(mApexService.getActivePackages()).thenReturn(createApexInfo(true, true)); + final ApexManager.ActiveApexInfo activeApex = mApexManager.getActiveApexInfos().get(0); + assertThat(activeApex.apexModuleName).isEqualTo(TEST_APEX_PKG); + + when(mApexService.getAllPackages()).thenReturn(createApexInfo(true, true)); + mApexManager.scanApexPackagesTraced(mPackageParser2, + ParallelPackageParser.makeExecutorService()); + + assertThat(mApexManager.isApkInApexInstallSuccess(activeApex.apexModuleName)).isTrue(); + mApexManager.reportErrorWithApkInApex(activeApex.apexDirectory.getAbsolutePath()); + assertThat(mApexManager.isApkInApexInstallSuccess(activeApex.apexModuleName)).isFalse(); + } + private ApexInfo[] createApexInfo(boolean isActive, boolean isFactory) { - File apexFile = copyRawResourceToFile(TEST_APEX_PKG, R.raw.apex_test); + File apexFile = extractResource(TEST_APEX_PKG, TEST_APEX_FILE_NAME); ApexInfo apexInfo = new ApexInfo(); apexInfo.isActive = isActive; apexInfo.isFactory = isFactory; apexInfo.moduleName = TEST_APEX_PKG; apexInfo.modulePath = apexFile.getPath(); apexInfo.versionCode = 191000070; + apexInfo.preinstalledModulePath = apexFile.getPath(); return new ApexInfo[]{apexInfo}; } @@ -308,27 +324,29 @@ public class ApexManagerTest { return params; } - /** - * Copies a specified {@code resourceId} to a temp file. Returns a non-null file if the copy - * succeeded - */ - File copyRawResourceToFile(String baseName, int resourceId) { - File outFile; + // Extracts the binary data from a resource and writes it to a temp file + private static File extractResource(String baseName, String fullResourceName) { + File file; try { - outFile = File.createTempFile(baseName, ".apex"); + file = File.createTempFile(baseName, ".apex"); } catch (IOException e) { throw new AssertionError("CreateTempFile IOException" + e); } - - try (InputStream is = mContext.getResources().openRawResource(resourceId); - FileOutputStream os = new FileOutputStream(outFile)) { - assertThat(FileUtils.copy(is, os)).isGreaterThan(0L); - } catch (FileNotFoundException e) { - throw new AssertionError("File not found exception " + e); + try ( + InputStream in = ApexManager.class.getClassLoader() + .getResourceAsStream(fullResourceName); + OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) { + if (in == null) { + throw new IllegalArgumentException("Resource not found: " + fullResourceName); + } + byte[] buf = new byte[65536]; + int chunkSize; + while ((chunkSize = in.read(buf)) != -1) { + out.write(buf, 0, chunkSize); + } + return file; } catch (IOException e) { - throw new AssertionError("IOException" + e); + throw new AssertionError("Exception while converting stream to file" + e); } - - return outFile; } } diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index acfe71a4a4b0..fa9ee19cba9d 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -35,6 +35,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.annotation.NonNull; +import android.app.PropertyInvalidatedCache; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -91,6 +92,12 @@ public class PackageManagerSettingsTests { MockitoAnnotations.initMocks(this); } + @Before + public void setup() { + // Disable binder caches in this process. + PropertyInvalidatedCache.disableForTestMode(); + } + /** make sure our initialized KeySetManagerService metadata matches packages.xml */ @Test public void testReadKeySetSettings() diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java index 7c3efeb01f48..1cfbad93c2e5 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java @@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import android.content.pm.PackageManager; @@ -32,6 +33,8 @@ import android.util.ArraySet; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.pm.pkg.PackageStateUnserialized; + import org.junit.Test; import org.junit.runner.RunWith; @@ -300,4 +303,55 @@ public class PackageUserStateTest { // Everything is different assertThat(params1.equals(params2), is(false)); } + + /** + * Test fix for b/149772100. + */ + private static void assertLastPackageUsageUnset( + PackageStateUnserialized state) throws Exception { + for (int i = state.getLastPackageUsageTimeInMills().length - 1; i >= 0; --i) { + assertEquals(0L, state.getLastPackageUsageTimeInMills()[i]); + } + } + private static void assertLastPackageUsageSet( + PackageStateUnserialized state, int reason, long value) throws Exception { + for (int i = state.getLastPackageUsageTimeInMills().length - 1; i >= 0; --i) { + if (i == reason) { + assertEquals(value, state.getLastPackageUsageTimeInMills()[i]); + } else { + assertEquals(0L, state.getLastPackageUsageTimeInMills()[i]); + } + } + } + @Test + public void testPackageUseReasons() throws Exception { + final PackageStateUnserialized testState1 = new PackageStateUnserialized(); + testState1.setLastPackageUsageTimeInMills(-1, 10L); + assertLastPackageUsageUnset(testState1); + + final PackageStateUnserialized testState2 = new PackageStateUnserialized(); + testState2.setLastPackageUsageTimeInMills( + PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT, 20L); + assertLastPackageUsageUnset(testState2); + + final PackageStateUnserialized testState3 = new PackageStateUnserialized(); + testState3.setLastPackageUsageTimeInMills(Integer.MAX_VALUE, 30L); + assertLastPackageUsageUnset(testState3); + + final PackageStateUnserialized testState4 = new PackageStateUnserialized(); + testState4.setLastPackageUsageTimeInMills(0, 40L); + assertLastPackageUsageSet(testState4, 0, 40L); + + final PackageStateUnserialized testState5 = new PackageStateUnserialized(); + testState5.setLastPackageUsageTimeInMills( + PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER, 50L); + assertLastPackageUsageSet( + testState5, PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER, 50L); + + final PackageStateUnserialized testState6 = new PackageStateUnserialized(); + testState6.setLastPackageUsageTimeInMills( + PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT - 1, 60L); + assertLastPackageUsageSet( + testState6, PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT - 1, 60L); + } } diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index 06b344b3b94f..efa25bd7721b 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -6734,6 +6734,21 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mManager.hasShareTargets(CALLING_PACKAGE_1); } + public void testisSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException { + setCaller(LAUNCHER_1, USER_0); + + IntentFilter filter_any = new IntentFilter(); + filter_any.addDataType("*/*"); + + assertExpectException(SecurityException.class, "Missing permission", () -> + mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0, + filter_any)); + + // Has permission, now it should pass. + mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS); + mManager.hasShareTargets(CALLING_PACKAGE_1); + } + public void testDumpsys_crossProfile() { prepareCrossProfileDataSet(); dumpsysOnLogcat("test1", /* force= */ true); @@ -8645,6 +8660,61 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { filter_any)); } + public void testIsSharingShortcut_PinnedAndCachedOnlyShortcuts() + throws IntentFilter.MalformedMimeTypeException { + addManifestShortcutResource( + new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), + R.xml.shortcut_share_targets); + updatePackageVersion(CALLING_PACKAGE_1, 1); + mService.mPackageMonitor.onReceive(getTestContext(), + genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); + + final ShortcutInfo s1 = makeShortcutWithCategory("s1", + set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2")); + final ShortcutInfo s2 = makeShortcutWithCategory("s2", + set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6")); + final ShortcutInfo s3 = makeShortcutWithCategory("s3", + set("com.test.category.CATEGORY5", "com.test.category.CATEGORY6")); + s1.setLongLived(); + s2.setLongLived(); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(s1, s2, s3))); + assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()), + "s1", "s2", "s3"); + }); + + IntentFilter filter_any = new IntentFilter(); + filter_any.addDataType("*/*"); + + setCaller(LAUNCHER_1, USER_0); + mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS); + + // Assert all are sharing shortcuts + assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0, + filter_any)); + assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0, + filter_any)); + assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0, + filter_any)); + + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + // Remove one cached shortcut, and leave one cached-only and pinned-only shortcuts. + mManager.removeLongLivedShortcuts(list("s1")); + mManager.removeDynamicShortcuts(list("s2, s3")); + }); + + assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0, + filter_any)); + assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0, + filter_any)); + assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0, + filter_any)); + } + private Uri getFileUriFromResource(String fileName, int resId) throws IOException { File file = new File(getTestContext().getFilesDir(), fileName); // Make sure we are not leaving phantom files behind. diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java new file mode 100644 index 000000000000..50d290a837cd --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java @@ -0,0 +1,775 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.pm; + +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.content.ComponentName; +import android.content.pm.LauncherApps.ShortcutChangeCallback; +import android.content.pm.LauncherApps.ShortcutQuery; +import android.content.pm.ShortcutInfo; +import android.os.test.TestLooper; + +import org.mockito.ArgumentCaptor; + +import java.util.List; + +/** + * Tests for {@link android.content.pm.LauncherApps.ShortcutChangeCallback} and relevant APIs. + * + atest -c com.android.server.pm.ShortcutManagerTest11 + */ +public class ShortcutManagerTest11 extends BaseShortcutManagerTest { + + private static final ShortcutQuery QUERY_MATCH_ALL = createShortcutQuery( + ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED); + + private final TestLooper mTestLooper = new TestLooper(); + + public void testShortcutChangeCallback_setDynamicShortcuts() { + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2"))); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1", "s2"); + } + + public void testShortcutChangeCallback_setDynamicShortcuts_replaceSameId() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2"))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s2", "s3"))); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2", "s3"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1"); + } + + public void testShortcutChangeCallback_setDynamicShortcuts_pinnedAndCached() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts( + list(makeShortcut("s1"), makeLongLivedShortcut("s2")))); + }); + + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0); + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s3", "s4"))); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1", "s2", "s3", "s4"); + } + + public void testShortcutChangeCallback_pinShortcuts() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2"))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1"); + } + + public void testShortcutChangeCallback_pinShortcuts_unpinOthers() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2", "s3"))); + }); + + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeDynamicShortcuts(list("s1", "s2")); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_0); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2", "s3"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1"); + } + + public void testShortcutChangeCallback_cacheShortcuts() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"), + makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_0); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1", "s3"); + } + + public void testShortcutChangeCallback_uncacheShortcuts() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"), + makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0); + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2"); + } + + public void testShortcutChangeCallback_uncacheShortcuts_causeDeletion() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"), + makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3")))); + }); + + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_0); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeDynamicShortcuts(list("s2", "s3")); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_0); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s3"); + } + + public void testShortcutChangeCallback_updateShortcuts() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"), + makeShortcutWithActivity("s2", new ComponentName(CALLING_PACKAGE_1, "test"))))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + final ComponentName updatedCn = new ComponentName(CALLING_PACKAGE_1, "updated activity"); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.updateShortcuts(list(makeShortcutWithActivity("s2", updatedCn)))); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2"); + assertEquals(updatedCn, ((ShortcutInfo) shortcuts.getValue().get(0)).getActivity()); + } + + public void testShortcutChangeCallback_addDynamicShortcuts() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1"))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.addDynamicShortcuts(makeShortcuts("s1", "s2"))); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1", "s2"); + } + + public void testShortcutChangeCallback_pushDynamicShortcut() { + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.pushDynamicShortcut(makeShortcut("s1")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1"); + } + + public void testShortcutChangeCallback_pushDynamicShortcut_existingId() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5", + "s6", "s7", "s8", "s9", "s10")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.pushDynamicShortcut(makeShortcut("s5")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s5"); + } + + public void testShortcutChangeCallback_pushDynamicShortcut_causeDeletion() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5", + "s6", "s7", "s8", "s9", "s10")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.pushDynamicShortcut(makeShortcut("s11")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s11"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s10"); + } + + public void testShortcutChangeCallback_pushDynamicShortcut_causeDeletionButCached() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5", + "s6", "s7", "s8", "s9")))); + ShortcutInfo s10 = makeLongLivedShortcut("s10"); + s10.setRank(10); + mManager.pushDynamicShortcut(s10); // Add a long lived shortcut to the end of the list. + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s10"), HANDLE_USER_0); + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.pushDynamicShortcut(makeShortcut("s11")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s10", "s11"); + } + + public void testShortcutChangeCallback_disableShortcuts() { + updatePackageVersion(CALLING_PACKAGE_1, 1); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2"))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.disableShortcuts(list("s2")); + }); + + mTestLooper.dispatchAll(); + + verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any()); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2"); + } + + public void testShortcutChangeCallback_disableShortcuts_pinnedAndCached() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts( + list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0); + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.disableShortcuts(list("s1", "s2", "s3")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2", "s3"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1"); + } + + public void testShortcutChangeCallback_enableShortcuts() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts( + list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3")))); + }); + + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.disableShortcuts(list("s1", "s2", "s3")); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.enableShortcuts(list("s1", "s2", "s3")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + verify(callback, times(0)).onShortcutsRemoved(any(), any(), any()); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2", "s3"); + } + + public void testShortcutChangeCallback_removeDynamicShortcuts() { + updatePackageVersion(CALLING_PACKAGE_1, 1); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2"))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeDynamicShortcuts(list("s2")); + }); + + mTestLooper.dispatchAll(); + + verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any()); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2"); + } + + public void testShortcutChangeCallback_removeDynamicShortcuts_pinnedAndCached() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"), + makeLongLivedShortcut("s2"), makeShortcut("s3"), makeShortcut("s4")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0); + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeDynamicShortcuts(list("s1", "s2", "s3")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2", "s3"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1"); + } + + public void testShortcutChangeCallback_removeAllDynamicShortcuts() { + updatePackageVersion(CALLING_PACKAGE_1, 1); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2"))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeAllDynamicShortcuts(); + }); + + mTestLooper.dispatchAll(); + + verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any()); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1", "s2"); + } + + public void testShortcutChangeCallback_removeAllDynamicShortcuts_pinnedAndCached() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts( + list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0); + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeAllDynamicShortcuts(); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s2", "s3"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1"); + } + + public void testShortcutChangeCallback_removeLongLivedShortcuts_notCached() { + updatePackageVersion(CALLING_PACKAGE_1, 1); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"), + makeLongLivedShortcut("s2"), makeShortcut("s3")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeLongLivedShortcuts(list("s1", "s2")); + }); + + mTestLooper.dispatchAll(); + + verify(callback, times(0)).onShortcutsAddedOrUpdated(any(), any(), any()); + + ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(shortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1", "s2"); + } + + public void testShortcutChangeCallback_removeLongLivedShortcuts_pinnedAndCached() { + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"), + makeLongLivedShortcut("s2"), makeShortcut("s3"), makeShortcut("s4")))); + }); + + ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); + runWithCaller(LAUNCHER_1, USER_0, () -> { + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0); + mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, + mTestLooper.getNewExecutor()); + }); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.removeLongLivedShortcuts(list("s1", "s2", "s3")); + }); + + mTestLooper.dispatchAll(); + + ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsAddedOrUpdated( + eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0)); + + ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onShortcutsRemoved( + eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0)); + + assertWith(changedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s3"); + + assertWith(removedShortcuts.getValue()) + .areAllWithKeyFieldsOnly() + .haveIds("s1", "s2"); + } + + private static ShortcutQuery createShortcutQuery(int queryFlags) { + ShortcutQuery q = new ShortcutQuery(); + return q.setQueryFlags(ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED); + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java index 9eaf8b645c37..44b202d60644 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java @@ -21,6 +21,7 @@ import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import android.app.PropertyInvalidatedCache; import android.content.pm.UserInfo; import android.os.Looper; import android.os.ServiceSpecificException; @@ -60,6 +61,9 @@ public class UserManagerServiceCreateProfileTest { if (Looper.myLooper() == null) { Looper.prepare(); } + // Disable binder caches in this process. + PropertyInvalidatedCache.disableForTestMode(); + LocalServices.removeServiceForTest(UserManagerInternal.class); mUserManagerService = new UserManagerService(InstrumentationRegistry.getContext()); diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java index a9ce6187b9ac..5846fc110d15 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.app.PropertyInvalidatedCache; import android.content.pm.UserInfo; import android.os.Looper; import android.os.UserManagerInternal; @@ -57,6 +58,9 @@ public class UserManagerServiceIdRecyclingTest { if (Looper.myLooper() == null) { Looper.prepare(); } + // Disable binder caches in this process. + PropertyInvalidatedCache.disableForTestMode(); + LocalServices.removeServiceForTest(UserManagerInternal.class); mUserManagerService = new UserManagerService(InstrumentationRegistry.getContext()); } @@ -122,4 +126,3 @@ public class UserManagerServiceIdRecyclingTest { return new UserInfo(userId, "User " + userId, 0); } } - diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java index 5df856865ff9..66ca839081bc 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java @@ -37,6 +37,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.annotation.UserIdInt; +import android.app.PropertyInvalidatedCache; import android.content.pm.UserInfo; import android.content.pm.UserInfo.UserInfoFlag; import android.os.Looper; @@ -78,6 +79,9 @@ public class UserManagerServiceUserInfoTest { if (Looper.myLooper() == null) { Looper.prepare(); } + // Disable binder caches in this process. + PropertyInvalidatedCache.disableForTestMode(); + LocalServices.removeServiceForTest(UserManagerInternal.class); mUserManagerService = new UserManagerService(InstrumentationRegistry.getContext()); diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java index 64d05f07e64e..102d5bb373c8 100644 --- a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.pm.VersionedPackage; import android.content.rollback.PackageRollbackInfo; import android.util.IntArray; +import android.util.SparseIntArray; import android.util.SparseLongArray; import com.google.common.truth.Correspondence; @@ -83,7 +84,7 @@ public class RollbackStoreTest { } }; - private static final String JSON_ROLLBACK = "{'info':{'rollbackId':123,'packages':" + private static final String JSON_ROLLBACK_NO_EXT = "{'info':{'rollbackId':123,'packages':" + "[{'versionRolledBackFrom':{'packageName':'blah','longVersionCode':55}," + "'versionRolledBackTo':{'packageName':'blah1','longVersionCode':50},'pendingBackups':" + "[59,1245,124544],'pendingRestores':[{'userId':498,'appId':32322,'seInfo':'wombles'}," @@ -103,6 +104,28 @@ public class RollbackStoreTest { + "'restoreUserDataInProgress':true, 'userId':0," + "'installerPackageName':'some.installer'}"; + private static final String JSON_ROLLBACK = "{'info':{'rollbackId':123,'packages':" + + "[{'versionRolledBackFrom':{'packageName':'blah','longVersionCode':55}," + + "'versionRolledBackTo':{'packageName':'blah1','longVersionCode':50},'pendingBackups':" + + "[59,1245,124544],'pendingRestores':[{'userId':498,'appId':32322,'seInfo':'wombles'}," + + "{'userId':-895,'appId':1,'seInfo':'pingu'}],'isApex':false,'isApkInApex':false," + + "'installedUsers':" + + "[498468432,1111,98464],'ceSnapshotInodes':[{'userId':1,'ceSnapshotInode':-6}," + + "{'userId':2222,'ceSnapshotInode':81641654445},{'userId':546546," + + "'ceSnapshotInode':345689375}]},{'versionRolledBackFrom':{'packageName':'chips'," + + "'longVersionCode':28},'versionRolledBackTo':{'packageName':'com.chips.test'," + + "'longVersionCode':48},'pendingBackups':[5],'pendingRestores':[{'userId':18," + + "'appId':-12,'seInfo':''}],'isApex':false,'isApkInApex':false," + + "'installedUsers':[55,79]," + + "'ceSnapshotInodes':[]}],'isStaged':false,'causePackages':[{'packageName':'hello'," + + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}]," + + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z'," + + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1," + + "'restoreUserDataInProgress':true, 'userId':0," + + "'installerPackageName':'some.installer'," + + "'extensionVersions':[{'sdkVersion':5,'extensionVersion':25}," + + "{'sdkVersion':30,'extensionVersion':71}]}"; + @Rule public TemporaryFolder mFolder = new TemporaryFolder(); @@ -119,7 +142,10 @@ public class RollbackStoreTest { @Test public void createNonStaged() { - Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null); + SparseIntArray extensionVersions = new SparseIntArray(); + extensionVersions.put(30, 71); + Rollback rollback = mRollbackStore.createNonStagedRollback( + ID, USER, INSTALLER, null, extensionVersions); assertThat(rollback.getBackupDir().getAbsolutePath()) .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); @@ -128,11 +154,16 @@ public class RollbackStoreTest { assertThat(rollback.info.getRollbackId()).isEqualTo(ID); assertThat(rollback.info.getPackages()).isEmpty(); assertThat(rollback.isEnabling()).isTrue(); + assertThat(rollback.getExtensionVersions().toString()) + .isEqualTo(extensionVersions.toString()); } @Test public void createStaged() { - Rollback rollback = mRollbackStore.createStagedRollback(ID, 897, USER, INSTALLER, null); + SparseIntArray extensionVersions = new SparseIntArray(); + extensionVersions.put(30, 71); + Rollback rollback = mRollbackStore.createStagedRollback( + ID, 897, USER, INSTALLER, null, extensionVersions); assertThat(rollback.getBackupDir().getAbsolutePath()) .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); @@ -143,11 +174,17 @@ public class RollbackStoreTest { assertThat(rollback.info.getRollbackId()).isEqualTo(ID); assertThat(rollback.info.getPackages()).isEmpty(); assertThat(rollback.isEnabling()).isTrue(); + assertThat(rollback.getExtensionVersions().toString()) + .isEqualTo(extensionVersions.toString()); } @Test public void saveAndLoadRollback() { - Rollback origRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null); + SparseIntArray extensionVersions = new SparseIntArray(); + extensionVersions.put(5, 25); + extensionVersions.put(30, 71); + Rollback origRb = mRollbackStore.createNonStagedRollback( + ID, USER, INSTALLER, null, extensionVersions); origRb.setRestoreUserDataInProgress(true); origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2)); @@ -196,8 +233,62 @@ public class RollbackStoreTest { } @Test + public void loadFromJsonNoExtensionVersions() throws Exception { + Rollback expectedRb = mRollbackStore.createNonStagedRollback( + ID, USER, INSTALLER, null, new SparseIntArray(0)); + + expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z")); + expectedRb.setRestoreUserDataInProgress(true); + expectedRb.info.getCausePackages().add(new VersionedPackage("hello", 23)); + expectedRb.info.getCausePackages().add(new VersionedPackage("something", 999)); + expectedRb.info.setCommittedSessionId(45654465); + + PackageRollbackInfo pkgInfo1 = new PackageRollbackInfo(new VersionedPackage("blah", 55), + new VersionedPackage("blah1", 50), new IntArray(), new ArrayList<>(), + false, false, new IntArray(), new SparseLongArray()); + pkgInfo1.getPendingBackups().add(59); + pkgInfo1.getPendingBackups().add(1245); + pkgInfo1.getPendingBackups().add(124544); + pkgInfo1.getCeSnapshotInodes().put(546546, 345689375); + pkgInfo1.getCeSnapshotInodes().put(2222, 81641654445L); + pkgInfo1.getCeSnapshotInodes().put(1, -6); + + pkgInfo1.getPendingRestores().add( + new PackageRollbackInfo.RestoreInfo(498, 32322, "wombles")); + pkgInfo1.getPendingRestores().add( + new PackageRollbackInfo.RestoreInfo(-895, 1, "pingu")); + + pkgInfo1.getSnapshottedUsers().add(498468432); + pkgInfo1.getSnapshottedUsers().add(1111); + pkgInfo1.getSnapshottedUsers().add(98464); + + PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(new VersionedPackage("chips", 28), + new VersionedPackage("com.chips.test", 48), new IntArray(), new ArrayList<>(), + false, false, new IntArray(), new SparseLongArray()); + pkgInfo2.getPendingBackups().add(5); + + pkgInfo2.getPendingRestores().add( + new PackageRollbackInfo.RestoreInfo(18, -12, "")); + + pkgInfo2.getSnapshottedUsers().add(55); + pkgInfo2.getSnapshottedUsers().add(79); + + expectedRb.info.getPackages().add(pkgInfo1); + expectedRb.info.getPackages().add(pkgInfo2); + + Rollback parsedRb = RollbackStore.rollbackFromJson( + new JSONObject(JSON_ROLLBACK_NO_EXT), expectedRb.getBackupDir()); + + assertRollbacksAreEquivalent(parsedRb, expectedRb); + } + + @Test public void loadFromJson() throws Exception { - Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null); + SparseIntArray extensionVersions = new SparseIntArray(); + extensionVersions.put(5, 25); + extensionVersions.put(30, 71); + Rollback expectedRb = mRollbackStore.createNonStagedRollback( + ID, USER, INSTALLER, null, extensionVersions); expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z")); expectedRb.setRestoreUserDataInProgress(true); @@ -246,7 +337,8 @@ public class RollbackStoreTest { @Test public void saveAndDelete() { - Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null); + Rollback rollback = mRollbackStore.createNonStagedRollback( + ID, USER, INSTALLER, null, new SparseIntArray(0)); RollbackStore.saveRollback(rollback); @@ -294,6 +386,13 @@ public class RollbackStoreTest { assertThat(a.getUserId()).isEqualTo(b.getUserId()); assertThat(a.getInstallerPackageName()).isEqualTo(b.getInstallerPackageName()); + + if (a.getExtensionVersions() == null) { + assertThat(b.getExtensionVersions()).isNull(); + } else { + assertThat(b.getExtensionVersions().toString()) + .isEqualTo(a.getExtensionVersions().toString()); + } } private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) { diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java index 1a6c6b4011cd..01c89b349687 100644 --- a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java +++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java @@ -24,12 +24,19 @@ import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import android.content.pm.PackageManagerInternal; import android.content.pm.VersionedPackage; import android.content.rollback.PackageRollbackInfo; import android.util.IntArray; +import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.SparseLongArray; +import com.android.server.pm.PackageList; +import com.android.server.pm.parsing.pkg.PackageImpl; + import com.google.common.collect.Range; import org.junit.Before; @@ -44,6 +51,7 @@ import java.io.File; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; @RunWith(JUnit4.class) public class RollbackUnitTest { @@ -56,10 +64,17 @@ public class RollbackUnitTest { private static final String INSTALLER = "some.installer"; @Mock private AppDataRollbackHelper mMockDataHelper; + @Mock private PackageManagerInternal mMockPmi; + + private List<String> mPackages; + private PackageList mPackageList; @Before public void setUp() { MockitoAnnotations.initMocks(this); + mPackages = new ArrayList<>(); + mPackageList = new PackageList(mPackages, null); + when(mMockPmi.getPackageList()).thenReturn(mPackageList); } @Test @@ -317,7 +332,7 @@ public class RollbackUnitTest { public void notifySessionWithSuccess() { int[] sessionIds = new int[]{ 7777, 8888 }; Rollback rollback = new Rollback(123, new File("/test/testing"), -1, USER, INSTALLER, - sessionIds); + sessionIds, new SparseIntArray(0)); // The 1st invocation returns false because not all child sessions are notified. assertThat(rollback.notifySessionWithSuccess()).isFalse(); // The 2nd invocation returns true because now all child sessions are notified. @@ -328,7 +343,7 @@ public class RollbackUnitTest { public void allPackagesEnabled() { int[] sessionIds = new int[]{ 7777, 8888 }; Rollback rollback = new Rollback(123, new File("/test/testing"), -1, USER, INSTALLER, - sessionIds); + sessionIds, new SparseIntArray(0)); // #allPackagesEnabled returns false when 1 out of 2 packages is enabled. rollback.info.getPackages().add(newPkgInfoFor(PKG_1, 12, 10, false)); assertThat(rollback.allPackagesEnabled()).isFalse(); @@ -340,6 +355,105 @@ public class RollbackUnitTest { assertThat(rollback.allPackagesEnabled()).isTrue(); } + @Test + public void readAndWriteStagedRollbackIdsFile() throws Exception { + File testFile = File.createTempFile("test", ".txt"); + RollbackPackageHealthObserver.writeStagedRollbackId(testFile, 2468, null); + RollbackPackageHealthObserver.writeStagedRollbackId(testFile, 12345, + new VersionedPackage("com.test.package", 1)); + RollbackPackageHealthObserver.writeStagedRollbackId(testFile, 13579, + new VersionedPackage("com.test.package2", 2)); + SparseArray<String> readInfo = + RollbackPackageHealthObserver.readStagedRollbackIds(testFile); + assertThat(readInfo.size()).isEqualTo(3); + + assertThat(readInfo.keyAt(0)).isEqualTo(2468); + assertThat(readInfo.valueAt(0)).isEqualTo(""); + assertThat(readInfo.keyAt(1)).isEqualTo(12345); + assertThat(readInfo.valueAt(1)).isEqualTo("com.test.package"); + assertThat(readInfo.keyAt(2)).isEqualTo(13579); + assertThat(readInfo.valueAt(2)).isEqualTo("com.test.package2"); + } + + @Test + public void minExtVerConstraintNotViolated() { + addPkgWithMinExtVersions("pkg0", new int[][] {{30, 4}}); + addPkgWithMinExtVersions("pkg1", new int[][] {}); + addPkgWithMinExtVersions("pkg2", new int[][] {{30, 5}, {31, 1}}); + addPkgWithMinExtVersions("pkg3", new int[][] {{31, 7}, {32, 15}}); + + assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( + sparseArrayFrom(new int[][] {{30, 5}}), mMockPmi)).isFalse(); + } + + @Test + public void minExtVerConstraintExists() { + addPkgWithMinExtVersions("pkg0", null); + addPkgWithMinExtVersions("pkg1", new int[][] {{30, 5}, {31, 1}}); + + assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( + sparseArrayFrom(new int[][] {{30, 4}}), mMockPmi)).isTrue(); + } + + @Test + public void minExtVerConstraintExistsOnOnePackage() { + addPkgWithMinExtVersions("pkg0", new int[][] {{30, 4}}); + addPkgWithMinExtVersions("pkg1", new int[][] {}); + addPkgWithMinExtVersions("pkg2", new int[][] {{30, 5}, {31, 1}}); + addPkgWithMinExtVersions("pkg3", new int[][] {{31, 7}, {32, 15}}); + + assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( + sparseArrayFrom(new int[][] {{30, 4}}), mMockPmi)).isTrue(); + } + + @Test + public void minExtVerConstraintDifferentSdk() { + addPkgWithMinExtVersions("pkg0", null); + addPkgWithMinExtVersions("pkg1", new int[][] {{30, 5}, {31, 1}}); + + assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( + sparseArrayFrom(new int[][] {{32, 4}}), mMockPmi)).isFalse(); + } + + @Test + public void minExtVerConstraintNoneRecordedOnRollback() { + addPkgWithMinExtVersions("pkg0", new int[][] {{30, 4}}); + addPkgWithMinExtVersions("pkg1", new int[][] {}); + addPkgWithMinExtVersions("pkg2", new int[][] {{30, 5}, {31, 1}}); + addPkgWithMinExtVersions("pkg3", new int[][] {{31, 7}, {32, 15}}); + + assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( + new SparseIntArray(0), mMockPmi)).isFalse(); + } + + @Test + public void minExtVerConstraintNoMinsRecorded() { + addPkgWithMinExtVersions("pkg0", null); + addPkgWithMinExtVersions("pkg1", null); + + assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( + sparseArrayFrom(new int[][] {{32, 4}}), mMockPmi)).isFalse(); + } + + private void addPkgWithMinExtVersions(String pkg, int[][] minExtVersions) { + mPackages.add(pkg); + PackageImpl pkgImpl = new PackageImpl(pkg, "baseCodePath", "codePath", null, false); + pkgImpl.setMinExtensionVersions(sparseArrayFrom(minExtVersions)); + + when(mMockPmi.getPackage(pkg)).thenReturn(pkgImpl); + } + + private static SparseIntArray sparseArrayFrom(int[][] arr) { + if (arr == null) { + return null; + } + SparseIntArray result = new SparseIntArray(arr.length); + for (int[] pair : arr) { + result.put(pair[0], pair[1]); + } + return result; + } + private static PackageRollbackInfo newPkgInfoFor( String packageName, long fromVersion, long toVersion, boolean isApex) { return new PackageRollbackInfo(new VersionedPackage(packageName, fromVersion), diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java index 229bd3f35cac..38b71b707196 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java @@ -15,10 +15,13 @@ */ package com.android.server.notification; -import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; +import static android.app.NotificationChannel.ALLOW_BUBBLE_OFF; +import static android.app.NotificationChannel.ALLOW_BUBBLE_ON; +import static android.app.NotificationChannel.DEFAULT_ALLOW_BUBBLE; import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; +import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; @@ -59,6 +62,7 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class BubbleExtractorTest extends UiServiceTestCase { + private static final String CHANNEL_ID = "bubbleExtractorChannelId"; private static final String SHORTCUT_ID = "shortcut"; private static final String PKG = "com.android.server.notification"; private static final String TAG = null; @@ -68,12 +72,11 @@ public class BubbleExtractorTest extends UiServiceTestCase { UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser()); BubbleExtractor mBubbleExtractor; + NotificationChannel mChannel; @Mock RankingConfig mConfig; @Mock - NotificationChannel mChannel; - @Mock Notification.BubbleMetadata mBubbleMetadata; @Mock PendingIntent mPendingIntent; @@ -95,7 +98,8 @@ public class BubbleExtractorTest extends UiServiceTestCase { mBubbleExtractor.setShortcutHelper(mShortcutHelper); mBubbleExtractor.setActivityManager(mActivityManager); - when(mConfig.getNotificationChannel(PKG, UID, "a", false)).thenReturn(mChannel); + mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, IMPORTANCE_DEFAULT); + when(mConfig.getNotificationChannel(PKG, UID, CHANNEL_ID, false)).thenReturn(mChannel); when(mShortcutInfo.getId()).thenReturn(SHORTCUT_ID); } @@ -147,10 +151,10 @@ public class BubbleExtractorTest extends UiServiceTestCase { when(mShortcutHelper.getValidShortcutInfo(SHORTCUT_ID, PKG, mUser)).thenReturn(answer); } - void setUpBubblesEnabled(boolean feature, int app, boolean channel) { + void setUpBubblesEnabled(boolean feature, int app, int channel) { when(mConfig.bubblesEnabled()).thenReturn(feature); when(mConfig.getBubblePreference(anyString(), anyInt())).thenReturn(app); - when(mChannel.canBubble()).thenReturn(channel); + mChannel.setAllowBubbles(channel); } // @@ -161,9 +165,8 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testAppYesChannelNo() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - false /* channel */); + ALLOW_BUBBLE_OFF /* channel */); NotificationRecord r = getNotificationRecord(true /* bubble */); - when(mChannel.getUserLockedFields()).thenReturn(USER_LOCKED_ALLOW_BUBBLE); mBubbleExtractor.process(r); assertFalse(r.canBubble()); @@ -171,23 +174,22 @@ public class BubbleExtractorTest extends UiServiceTestCase { } @Test - public void testAppNoChannelYes() throws Exception { + public void testAppYesChannelDefault() { setUpBubblesEnabled(true /* feature */, - BUBBLE_PREFERENCE_NONE /* app */, - true /* channel */); + BUBBLE_PREFERENCE_ALL /* app */, + DEFAULT_ALLOW_BUBBLE /* channel */); NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); - assertFalse(r.canBubble()); - assertFalse(r.getNotification().isBubbleNotification()); + assertTrue(r.canBubble()); } @Test public void testAppYesChannelYes() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + ALLOW_BUBBLE_ON /* channel */); NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); @@ -196,10 +198,23 @@ public class BubbleExtractorTest extends UiServiceTestCase { } @Test - public void testAppNoChannelNo() { + public void testAppYesChannelYesFeatureNo() { + setUpBubblesEnabled(false /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + ALLOW_BUBBLE_ON /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); + + mBubbleExtractor.process(r); + + assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testAppNoChannelYes() throws Exception { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_NONE /* app */, - false /* channel */); + ALLOW_BUBBLE_ON /* channel */); NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); @@ -209,10 +224,23 @@ public class BubbleExtractorTest extends UiServiceTestCase { } @Test - public void testAppYesChannelYesUserNo() { - setUpBubblesEnabled(false /* feature */, - BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + public void testAppNoChannelDefault() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_NONE /* app */, + DEFAULT_ALLOW_BUBBLE /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); + + mBubbleExtractor.process(r); + + assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testAppSelectedChannelDefault() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_SELECTED /* app */, + DEFAULT_ALLOW_BUBBLE /* channel */); NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); @@ -225,7 +253,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testAppSelectedChannelNo() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_SELECTED /* app */, - false /* channel */); + ALLOW_BUBBLE_OFF /* channel */); NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); @@ -238,15 +266,27 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testAppSeletedChannelYes() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_SELECTED /* app */, - true /* channel */); + ALLOW_BUBBLE_ON /* channel */); NotificationRecord r = getNotificationRecord(true /* bubble */); - when(mChannel.getUserLockedFields()).thenReturn(USER_LOCKED_ALLOW_BUBBLE); mBubbleExtractor.process(r); assertTrue(r.canBubble()); } + @Test + public void testAppSeletedChannelYesFeatureNo() { + setUpBubblesEnabled(false /* feature */, + BUBBLE_PREFERENCE_SELECTED /* app */, + ALLOW_BUBBLE_ON /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); + + mBubbleExtractor.process(r); + + assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + // // Tests for flagging it as a bubble. // @@ -255,7 +295,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_previouslyRemoved() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); setUpShortcutBubble(true /* isValid */); @@ -272,7 +312,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_true_shortcutBubble() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); setUpShortcutBubble(true /* isValid */); @@ -287,7 +327,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_true_intentBubble() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); setUpIntentBubble(true /* isValid */); @@ -302,7 +342,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_noIntentInvalidShortcut() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); setUpShortcutBubble(false /* isValid */); @@ -318,7 +358,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_invalidIntentNoShortcut() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); setUpIntentBubble(false /* isValid */); @@ -334,7 +374,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_noIntentNoShortcut() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); // Shortcut here is for the notification not the bubble @@ -349,7 +389,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_noMetadata() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); NotificationRecord r = getNotificationRecord(false /* bubble */); @@ -363,7 +403,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_notConversation() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(false); setUpIntentBubble(true /* isValid */); @@ -382,7 +422,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_lowRamDevice() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(true); setUpIntentBubble(true /* isValid */); @@ -397,7 +437,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_noIntent() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(true); setUpIntentBubble(true /* isValid */); when(mPendingIntent.getIntent()).thenReturn(null); @@ -413,7 +453,7 @@ public class BubbleExtractorTest extends UiServiceTestCase { public void testFlagBubble_false_noActivityInfo() { setUpBubblesEnabled(true /* feature */, BUBBLE_PREFERENCE_ALL /* app */, - true /* channel */); + DEFAULT_ALLOW_BUBBLE /* channel */); when(mActivityManager.isLowRamDevice()).thenReturn(true); setUpIntentBubble(true /* isValid */); when(mPendingIntent.getIntent()).thenReturn(mIntent); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java index a23ade68b344..77ce2f032a09 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java @@ -76,8 +76,6 @@ public class NotificationChannelExtractorTest extends UiServiceTestCase { @Test public void testInvalidShortcutFlagEnabled_looksUpCorrectChannel() { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0); NotificationChannelExtractor extractor = new NotificationChannelExtractor(); extractor.setConfig(mConfig); @@ -96,7 +94,7 @@ public class NotificationChannelExtractorTest extends UiServiceTestCase { NotificationChannel updatedChannel = new NotificationChannel("a", "", IMPORTANCE_HIGH); when(mConfig.getConversationNotificationChannel( - any(), anyInt(), eq("a"), eq(r.getSbn().getShortcutId(mContext)), + any(), anyInt(), eq("a"), eq(r.getSbn().getShortcutId()), eq(true), eq(false))) .thenReturn(updatedChannel); @@ -106,8 +104,6 @@ public class NotificationChannelExtractorTest extends UiServiceTestCase { @Test public void testInvalidShortcutFlagDisabled_looksUpCorrectChannel() { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); NotificationChannelExtractor extractor = new NotificationChannelExtractor(); extractor.setConfig(mConfig); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 41748b8a893b..d5ecfeb55e95 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -6589,14 +6589,45 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testRecordMessages() throws RemoteException { + public void testRecordMessages_invalidMsg() throws RemoteException { NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, - "testRecordMessages"); + "testRecordMessages_invalidMsg"); mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); waitForIdle(); assertTrue(mBinderService.hasSentMessage(PKG, mUid)); } + + @Test + public void testRecordMessages_validMsg() throws RemoteException { + // Messaging notification with shortcut info + Notification.BubbleMetadata metadata = + new Notification.BubbleMetadata.Builder("id").build(); + Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */, + null /* groupKey */, false /* isSummary */); + nb.setShortcutId("id"); + nb.setBubbleMetadata(metadata); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, + "testRecordMessages_validMsg", mUid, 0, nb.build(), new UserHandle(mUid), null, 0); + NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + // Pretend the shortcut exists + List<ShortcutInfo> shortcutInfos = new ArrayList<>(); + ShortcutInfo info = mock(ShortcutInfo.class); + when(info.getPackage()).thenReturn(PKG); + when(info.getId()).thenReturn("id"); + when(info.getUserId()).thenReturn(USER_SYSTEM); + when(info.isLongLived()).thenReturn(true); + when(info.isEnabled()).thenReturn(true); + shortcutInfos.add(info); + when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos); + + mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), + nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); + waitForIdle(); + + assertFalse(mBinderService.hasSentMessage(PKG, mUid)); + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java index 3139bfaaf1f5..9f593ce42741 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java @@ -123,8 +123,6 @@ public class NotificationRecordTest extends UiServiceTestCase { when(mMockContext.getResources()).thenReturn(getContext().getResources()); when(mMockContext.getPackageManager()).thenReturn(mPm); when(mMockContext.getContentResolver()).thenReturn(mContentResolver); - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); ApplicationInfo appInfo = new ApplicationInfo(); appInfo.targetSdkVersion = Build.VERSION_CODES.O; when(mMockContext.getApplicationInfo()).thenReturn(appInfo); @@ -1127,18 +1125,7 @@ public class NotificationRecordTest extends UiServiceTestCase { } @Test - public void testIsConversation_nullShortcut() { - StatusBarNotification sbn = getMessagingStyleNotification(); - NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); - record.setShortcutInfo(null); - - assertFalse(record.isConversation()); - } - - @Test - public void testIsConversation_bypassShortcutFlagEnabled() { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0); + public void testIsConversation_noShortcut() { StatusBarNotification sbn = getMessagingStyleNotification(); NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); record.setShortcutInfo(null); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java index 0d44318e4aaa..00061931b18d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java @@ -98,7 +98,8 @@ public class NotificationShellCmdTest extends UiServiceTestCase { } private void doCmd(String... args) { - new NotificationShellCmd(mMockService) + System.out.println("Running command: " + String.join(" ", args)); + new TestNotificationShellCmd(mMockService) .exec(mBinder, in, out, err, args, mCallback, mResultReceiver); } @@ -267,4 +268,19 @@ public class NotificationShellCmdTest extends UiServiceTestCase { } } + + /** + * Version of NotificationShellCmd that allows this atest to work properly despite coming in + * from the wrong uid. + */ + private final class TestNotificationShellCmd extends NotificationShellCmd { + TestNotificationShellCmd(NotificationManagerService service) { + super(service); + } + + @Override + protected boolean checkShellCommandPermission(int callingUid) { + return true; + } + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index e11392bde993..4320f1c3c896 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -3023,31 +3023,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testPlaceholderConversationId_shortcutNotRequired() throws Exception { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0); - - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, - mAppOpsManager); - - final String xml = "<ranking version=\"1\">\n" - + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" - + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>" - + "</package>" - + "</ranking>"; - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), - null); - parser.nextTag(); - mHelper.readXml(parser, false, UserHandle.USER_ALL); - - assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true)); - } - - @Test public void testPlaceholderConversationId_shortcutRequired() throws Exception { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, mAppOpsManager); @@ -3067,8 +3043,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testNormalConversationId_shortcutRequired() throws Exception { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, mAppOpsManager); @@ -3088,8 +3062,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testNoConversationId_shortcutRequired() throws Exception { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, mAppOpsManager); @@ -3276,6 +3248,19 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test + public void testGetConversations_noDemoted() { + NotificationChannel parent = new NotificationChannel("parent", "p", 1); + mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false); + NotificationChannel channel = + new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT); + channel.setConversationId("parent", "convo"); + channel.setDemoted(true); + mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false); + + assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty(); + } + + @Test public void testGetConversations() { NotificationChannelGroup group = new NotificationChannelGroup("acct", "account_name"); mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java index 3095c87ba2f6..eb2d9fed197f 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java @@ -40,6 +40,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -184,6 +185,7 @@ public class ShortcutHelperTest extends UiServiceTestCase { assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull(); } + @Ignore("b/155016294") @Test public void testGetValidShortcutInfo_notSharingShortcut() { ShortcutInfo si = mock(ShortcutInfo.class); @@ -229,8 +231,9 @@ public class ShortcutHelperTest extends UiServiceTestCase { ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); shortcuts.add(si); when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts); - when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), - anyString(), anyInt(), any())).thenReturn(true); + // TODO: b/155016294 + //when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + // anyString(), anyInt(), any())).thenReturn(true); assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isSameAs(si); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 6a28918eab00..8cfe96f0db5a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -66,6 +66,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.never; import android.app.ActivityOptions; @@ -1083,6 +1084,46 @@ public class ActivityRecordTests extends ActivityTestsBase { } /** + * Verify that complete finish request for an activity which the resume activity is translucent + * must ensure the visibilities of activities being updated. + */ + @Test + public void testCompleteFinishing_ensureActivitiesVisible() { + final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); + firstActivity.mVisibleRequested = false; + firstActivity.nowVisible = false; + firstActivity.setState(STOPPED, "true"); + + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build(); + secondActivity.mVisibleRequested = true; + secondActivity.nowVisible = true; + secondActivity.setState(PAUSED, "true"); + + final ActivityRecord translucentActivity = + new ActivityBuilder(mService).setTask(mTask).build(); + translucentActivity.mVisibleRequested = true; + translucentActivity.nowVisible = true; + translucentActivity.setState(RESUMED, "true"); + + doReturn(false).when(translucentActivity).occludesParent(); + + // Finish the second activity + secondActivity.finishing = true; + secondActivity.completeFinishing("test"); + verify(secondActivity.getDisplay()).ensureActivitiesVisible(null /* starting */, + 0 /* configChanges */ , false /* preserveWindows */, + true /* notifyClients */); + + // Finish the first activity + firstActivity.finishing = true; + firstActivity.mVisibleRequested = true; + firstActivity.completeFinishing("test"); + verify(firstActivity.getDisplay(), times(2)).ensureActivitiesVisible(null /* starting */, + 0 /* configChanges */ , false /* preserveWindows */, + true /* notifyClients */); + } + + /** * Verify destroy activity request completes successfully. */ @Test @@ -1362,6 +1403,7 @@ public class ActivityRecordTests extends ActivityTestsBase { final DisplayInfo rotatedInfo = mActivity.getFixedRotationTransformDisplayInfo(); mActivity.finishFixedRotationTransform(); final ScreenRotationAnimation rotationAnim = display.getRotationAnimation(); + assertNotNull(rotationAnim); rotationAnim.setRotation(display.getPendingTransaction(), originalRotation); // Because the display doesn't rotate, the rotated activity needs to cancel the fixed @@ -1369,8 +1411,18 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(mActivity).onCancelFixedRotationTransform(rotatedInfo.rotation); assertTrue(mActivity.isFreezingScreen()); assertFalse(displayRotation.isRotatingSeamlessly()); - assertNotNull(rotationAnim); assertTrue(rotationAnim.isRotating()); + + // Simulate the remote rotation has completed and the configuration doesn't change, then + // the rotated activity should also be restored by clearing the transform. + displayRotation.updateRotationUnchecked(true /* forceUpdate */); + doReturn(false).when(displayRotation).isWaitingForRemoteRotation(); + clearInvocations(mActivity); + display.mFixedRotationLaunchingApp = mActivity; + display.sendNewConfiguration(); + + assertNull(display.mFixedRotationLaunchingApp); + assertFalse(mActivity.hasFixedRotationTransform()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 6c209e496cf6..5227f3c885ba 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -234,6 +234,25 @@ public class ActivityStackTests extends ActivityTestsBase { } @Test + public void testRemoveOrganizedTask_UpdateStackReference() { + final ActivityStack rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask(); + final ActivityRecord homeActivity = new ActivityBuilder(mService) + .setStack(rootHomeTask) + .setCreateTask(true) + .build(); + final ActivityStack secondaryStack = (ActivityStack) WindowContainer.fromBinder( + mService.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(), + WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token.asBinder()); + + rootHomeTask.reparent(secondaryStack, POSITION_TOP); + assertEquals(secondaryStack, rootHomeTask.getParent()); + + // This should call to {@link TaskDisplayArea#removeStackReferenceIfNeeded}. + homeActivity.removeImmediately(); + assertNull(mDefaultTaskDisplayArea.getRootHomeTask()); + } + + @Test public void testStackInheritsDisplayWindowingMode() { final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */); 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 a84a0a2260b2..edc9756d6d0e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -808,6 +808,41 @@ public class ActivityStarterTests extends ActivityTestsBase { verify(secondaryTaskContainer, times(2)).createStack(anyInt(), anyInt(), anyBoolean()); } + @Test + public void testWasVisibleInRestartAttempt() { + final ActivityStarter starter = prepareStarter( + FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | FLAG_ACTIVITY_SINGLE_TOP, false); + final ActivityRecord reusableActivity = + new ActivityBuilder(mService).setCreateTask(true).build(); + final ActivityRecord topActivity = + new ActivityBuilder(mService).setCreateTask(true).build(); + + // Make sure topActivity is on top + topActivity.getRootTask().moveToFront("testWasVisibleInRestartAttempt"); + reusableActivity.setVisible(false); + + final TaskChangeNotificationController taskChangeNotifier = + mService.getTaskChangeNotificationController(); + spyOn(taskChangeNotifier); + + Task task = topActivity.getTask(); + starter.postStartActivityProcessing( + task.getTopNonFinishingActivity(), START_DELIVERED_TO_TOP, task.getStack()); + + verify(taskChangeNotifier).notifyActivityRestartAttempt( + any(), anyBoolean(), anyBoolean(), anyBoolean()); + verify(taskChangeNotifier).notifyActivityRestartAttempt( + any(), anyBoolean(), anyBoolean(), eq(true)); + + Task task2 = reusableActivity.getTask(); + starter.postStartActivityProcessing( + task2.getTopNonFinishingActivity(), START_TASK_TO_FRONT, task.getStack()); + verify(taskChangeNotifier, times(2)).notifyActivityRestartAttempt( + any(), anyBoolean(), anyBoolean(), anyBoolean()); + verify(taskChangeNotifier).notifyActivityRestartAttempt( + any(), anyBoolean(), anyBoolean(), eq(false)); + } + private ActivityRecord createSingleTaskActivityOn(ActivityStack stack) { final ComponentName componentName = ComponentName.createRelative( DEFAULT_COMPONENT_PACKAGE_NAME, diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 17dd26ed18e9..4b43ceb6e07f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -39,6 +39,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; import android.view.IDisplayWindowListener; import androidx.test.filters.MediumTest; @@ -57,6 +58,7 @@ import java.util.ArrayList; * Build/Install/Run: * atest WmTests:ActivityTaskManagerServiceTests */ +@Presubmit @MediumTest @RunWith(WindowTestRunner.class) public class ActivityTaskManagerServiceTests extends ActivityTestsBase { diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java index 0700f9f2b29c..2991859c5dd4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -49,6 +49,7 @@ import android.os.Build; import android.os.Bundle; import android.os.UserHandle; import android.service.voice.IVoiceInteractionSession; +import android.view.SurfaceControl; import android.window.ITaskOrganizer; import android.window.WindowContainerToken; @@ -552,7 +553,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { mMoveToSecondaryOnEnter = move; } @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo info) { + public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) { } @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java index 307b40f1b039..6a1f50d7e58a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java @@ -27,6 +27,8 @@ import android.graphics.Rect; import android.os.Binder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.view.SurfaceControl; +import android.window.DisplayAreaInfo; import android.window.IDisplayAreaOrganizer; import androidx.test.filters.SmallTest; @@ -74,7 +76,8 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase { @Test public void testAppearedVanished() throws RemoteException { IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); - verify(organizer).onDisplayAreaAppeared(any()); + verify(organizer) + .onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class)); unregisterMockOrganizer(organizer); verify(organizer).onDisplayAreaVanished(any()); @@ -83,7 +86,8 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase { @Test public void testChanged() throws RemoteException { IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); - verify(organizer).onDisplayAreaAppeared(any()); + verify(organizer) + .onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class)); mDisplayContent.setBounds(new Rect(0, 0, 1000, 1000)); verify(organizer).onDisplayAreaInfoChanged(any()); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index e02ea813cdd7..cba89d0aea2d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -790,9 +790,7 @@ public class DisplayContentTests extends WindowTestsBase { final DisplayContent dc = createNewDisplay(); dc.getDisplayRotation().setFixedToUserRotation( IWindowManager.FIXED_TO_USER_ROTATION_DISABLED); - final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE - ? SCREEN_ORIENTATION_PORTRAIT - : SCREEN_ORIENTATION_LANDSCAPE; + final int newOrientation = getRotatedOrientation(dc); final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) @@ -812,9 +810,7 @@ public class DisplayContentTests extends WindowTestsBase { final DisplayContent dc = createNewDisplay(); dc.getDisplayRotation().setFixedToUserRotation( IWindowManager.FIXED_TO_USER_ROTATION_ENABLED); - final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE - ? SCREEN_ORIENTATION_PORTRAIT - : SCREEN_ORIENTATION_LANDSCAPE; + final int newOrientation = getRotatedOrientation(dc); final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) @@ -1083,7 +1079,8 @@ public class DisplayContentTests extends WindowTestsBase { mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */); mDisplayContent.mOpeningApps.add(app); - app.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); + final int newOrientation = getRotatedOrientation(mDisplayContent); + app.setRequestedOrientation(newOrientation); assertTrue(app.isFixedRotationTransforming()); assertTrue(mDisplayContent.getDisplayRotation().shouldRotateSeamlessly( @@ -1124,12 +1121,25 @@ public class DisplayContentTests extends WindowTestsBase { mWallpaperWindow.mToken.onAnimationLeashCreated(t, null /* leash */); verify(t, never()).setPosition(any(), eq(0), eq(0)); + // Launch another activity before the transition is finished. + final ActivityRecord app2 = new ActivityTestsBase.StackBuilder(mWm.mRoot) + .setDisplay(mDisplayContent).build().getTopMostActivity(); + mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN, + false /* alwaysKeepCurrent */); + mDisplayContent.mOpeningApps.add(app2); + app2.setRequestedOrientation(newOrientation); + + // The activity should share the same transform state as the existing one. + assertTrue(app.hasFixedRotationTransform(app2)); + + // The display should be rotated after the launch is finished. mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token); // The animation in old rotation should be cancelled. assertFalse(closingApp.isAnimating()); - // The display should be rotated after the launch is finished. + // The fixed rotation should be cleared and the new rotation is applied to display. assertFalse(app.hasFixedRotationTransform()); + assertFalse(app2.hasFixedRotationTransform()); assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation); } @@ -1292,6 +1302,12 @@ public class DisplayContentTests extends WindowTestsBase { assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop))); } + private static int getRotatedOrientation(DisplayContent dc) { + return dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE + ? SCREEN_ORIENTATION_PORTRAIT + : SCREEN_ORIENTATION_LANDSCAPE; + } + private static List<WindowState> reverseList(List<WindowState> list) { final ArrayList<WindowState> result = new ArrayList<>(list); Collections.reverse(result); diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java index f8117573efdd..ca016761438b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java @@ -189,4 +189,25 @@ public class InsetsSourceProviderTest extends WindowTestsBase { mProvider.onInsetsModified(target, state.getSource(ITYPE_STATUS_BAR)); assertTrue(mSource.isVisible()); } + + @Test + public void testInsetGeometries() { + final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); + statusBar.getFrameLw().set(0, 0, 500, 100); + statusBar.mHasSurface = true; + mProvider.setWindow(statusBar, null, null); + mProvider.onPostLayout(); + assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame()); + // Still apply top insets if window overlaps even if it's top doesn't exactly match + // the inset-window's top. + assertEquals(Insets.of(0, 100, 0, 0), + mProvider.getSource().calculateInsets(new Rect(0, -100, 500, 400), + false /* ignoreVisibility */)); + + // Don't apply left insets if window is left-of inset-window but still overlaps + statusBar.getFrameLw().set(100, 0, 0, 0); + assertEquals(Insets.of(0, 0, 0, 0), + mProvider.getSource().calculateInsets(new Rect(-100, 0, 400, 500), + false /* ignoreVisibility */)); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index f19550ced0bf..906646894ee0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -344,9 +344,17 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity); + assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp); + // Check that the home app is in portrait assertEquals(Configuration.ORIENTATION_PORTRAIT, homeActivity.getConfiguration().orientation); + + // Home activity won't become top (return to landActivity), so its fixed rotation and the + // top rotated record should be cleared. + mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); + assertFalse(homeActivity.hasFixedRotationTransform()); + assertNull(mDefaultDisplay.mFixedRotationLaunchingApp); } @Test @@ -401,12 +409,16 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertEquals(Configuration.ORIENTATION_PORTRAIT, wallpapers.get(0).getConfiguration().orientation); - // Wallpaper's transform state is controlled by home, so the invocation should be no-op. - wallpaperWindowToken.finishFixedRotationTransform(); - assertTrue(wallpaperWindowToken.hasFixedRotationTransform()); + mController.cleanupAnimation(REORDER_MOVE_TO_TOP); + // The transform state should keep because we expect to listen the signal from the + // transition executed by moving the task to front. + assertTrue(homeActivity.hasFixedRotationTransform()); + assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp); + mDefaultDisplay.mFixedRotationTransitionListener.onAppTransitionFinishedLocked( + homeActivity.token); // Wallpaper's transform state should be cleared with home. - homeActivity.finishFixedRotationTransform(); + assertFalse(homeActivity.hasFixedRotationTransform()); assertFalse(wallpaperWindowToken.hasFixedRotationTransform()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index dea9294ff75b..bce1320f1d7e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -335,7 +335,11 @@ public class SystemServicesTestRule implements TestRule { mWmService.mConstants.dispose(); mWmService.mHighRefreshRateBlacklist.dispose(); + // This makes sure the posted messages without delay are processed, e.g. + // DisplayPolicy#release, WindowManagerService#setAnimationScale. waitUntilWindowManagerHandlersIdle(); + // Clear all posted messages with delay, so they don't be executed at unexpected times. + cleanupWindowManagerHandlers(); // Needs to explicitly dispose current static threads because there could be messages // scheduled at a later time, and all mocks are invalid when it's executed. DisplayThread.dispose(); @@ -399,8 +403,6 @@ public class SystemServicesTestRule implements TestRule { if (wm == null) { return; } - // Removing delayed FORCE_GC message decreases time for waiting idle. - wm.mH.removeMessages(WindowManagerService.H.FORCE_GC); waitHandlerIdle(wm.mH); waitHandlerIdle(wm.mAnimationHandler); // This is a different handler object than the wm.mAnimationHandler above. @@ -408,25 +410,8 @@ public class SystemServicesTestRule implements TestRule { waitHandlerIdle(SurfaceAnimationThread.getHandler()); } - private void waitHandlerIdle(Handler handler) { - synchronized (mCurrentMessagesProcessed) { - // Add a message to the handler queue and make sure it is fully processed before we move - // on. This makes sure all previous messages in the handler are fully processed vs. just - // popping them from the message queue. - mCurrentMessagesProcessed.set(false); - handler.post(() -> { - synchronized (mCurrentMessagesProcessed) { - mCurrentMessagesProcessed.set(true); - mCurrentMessagesProcessed.notifyAll(); - } - }); - while (!mCurrentMessagesProcessed.get()) { - try { - mCurrentMessagesProcessed.wait(); - } catch (InterruptedException e) { - } - } - } + static void waitHandlerIdle(Handler handler) { + handler.runWithScissors(() -> { }, 0 /* timeout */); } void waitUntilWindowAnimatorIdle() { diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java index 6e41118997ac..9872faaf6582 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertTrue; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.TaskDescription; +import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.ActivityView; import android.app.IActivityManager; @@ -43,6 +44,7 @@ import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.support.test.uiautomator.UiDevice; import android.text.TextUtils; +import android.view.Display; import android.view.ViewGroup; import androidx.test.filters.FlakyTest; @@ -319,15 +321,91 @@ public class TaskStackChangedListenerTest { waitForCallback(singleTaskDisplayEmptyLatch); } + @Test + public void testTaskDisplayChanged() throws Exception { + final CountDownLatch activityViewReadyLatch = new CountDownLatch(1); + final ActivityViewTestActivity activity = + (ActivityViewTestActivity) startTestActivity(ActivityViewTestActivity.class); + final ActivityView activityView = activity.getActivityView(); + activityView.setCallback(new ActivityView.StateCallback() { + @Override + public void onActivityViewReady(ActivityView view) { + activityViewReadyLatch.countDown(); + } + @Override + public void onActivityViewDestroyed(ActivityView view) {} + }); + waitForCallback(activityViewReadyLatch); + + // Launch a Activity inside ActivityView. + final Object[] params1 = new Object[1]; + final CountDownLatch displayChangedLatch1 = new CountDownLatch(1); + final int activityViewDisplayId = activityView.getVirtualDisplayId(); + registerTaskStackChangedListener( + new TaskDisplayChangedListener( + activityViewDisplayId, params1, displayChangedLatch1)); + int taskId1; + ActivityOptions options1 = ActivityOptions.makeBasic() + .setLaunchDisplayId(activityView.getVirtualDisplayId()); + synchronized (sLock) { + taskId1 = startTestActivity(ActivityInActivityView.class, options1).getTaskId(); + } + waitForCallback(displayChangedLatch1); + + assertEquals(taskId1, params1[0]); + + // Launch the Activity in the default display, expects that reparenting happens. + final Object[] params2 = new Object[1]; + final CountDownLatch displayChangedLatch2 = new CountDownLatch(1); + registerTaskStackChangedListener( + new TaskDisplayChangedListener( + Display.DEFAULT_DISPLAY, params2, displayChangedLatch2)); + int taskId2; + ActivityOptions options2 = ActivityOptions.makeBasic() + .setLaunchDisplayId(Display.DEFAULT_DISPLAY); + synchronized (sLock) { + taskId2 = startTestActivity(ActivityInActivityView.class, options2).getTaskId(); + } + waitForCallback(displayChangedLatch2); + + assertEquals(taskId2, params2[0]); + assertEquals(taskId1, taskId2); // TaskId should be same since reparenting happens. + } + + private static class TaskDisplayChangedListener extends TaskStackListener { + private int mDisplayId; + private final Object[] mParams; + private final CountDownLatch mDisplayChangedLatch; + TaskDisplayChangedListener( + int displayId, Object[] params, CountDownLatch displayChangedLatch) { + mDisplayId = displayId; + mParams = params; + mDisplayChangedLatch = displayChangedLatch; + } + @Override + public void onTaskDisplayChanged(int taskId, int displayId) throws RemoteException { + // Filter out the events for the uninterested displays. + // if (displayId != mDisplayId) return; + mParams[0] = taskId; + mDisplayChangedLatch.countDown(); + } + }; + /** * Starts the provided activity and returns the started instance. */ private TestActivity startTestActivity(Class<?> activityClass) throws InterruptedException { + return startTestActivity(activityClass, ActivityOptions.makeBasic()); + } + + private TestActivity startTestActivity(Class<?> activityClass, ActivityOptions options) + throws InterruptedException { final ActivityMonitor monitor = new ActivityMonitor(activityClass.getName(), null, false); getInstrumentation().addMonitor(monitor); final Context context = getInstrumentation().getContext(); context.startActivity( - new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), + options.toBundle()); final TestActivity activity = (TestActivity) monitor.waitForActivityWithTimeout(1000); if (activity == null) { throw new RuntimeException("Timed out waiting for Activity"); @@ -337,6 +415,9 @@ public class TaskStackChangedListenerTest { } private void registerTaskStackChangedListener(ITaskStackListener listener) throws Exception { + if (mTaskStackListener != null) { + ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener); + } mTaskStackListener = listener; ActivityTaskManager.getService().registerTaskStackListener(listener); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java index f354a04101f5..9fdb9d8f9844 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java @@ -72,6 +72,13 @@ public class TaskStackTests extends WindowTestsBase { stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */); assertEquals(stack.mChildren.get(0), task2); assertEquals(stack.mChildren.get(1), task1); + + // Non-leaf task should be moved to top regardless of the user id. + createTaskInStack((ActivityStack) task2, 0 /* userId */); + createTaskInStack((ActivityStack) task2, 1 /* userId */); + stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */); + assertEquals(stack.mChildren.get(0), task1); + assertEquals(stack.mChildren.get(1), task2); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java index 926bd8c9846a..8d5363c89570 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.verify; import android.content.ContentResolver; import android.net.Uri; +import android.platform.test.annotations.Presubmit; import android.provider.Settings; import androidx.test.filters.SmallTest; @@ -43,6 +44,7 @@ import org.junit.runner.RunWith; * Build/Install/Run: * atest WmTests:WindowManagerSettingsTests */ +@Presubmit @SmallTest @RunWith(WindowTestRunner.class) public class WindowManagerSettingsTests extends WindowTestsBase { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 7d2e88014f45..aa68c6900f6f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -65,6 +65,7 @@ import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; import android.util.Rational; import android.view.Display; +import android.view.SurfaceControl; import android.window.ITaskOrganizer; import android.window.WindowContainerTransaction; @@ -133,7 +134,8 @@ public class WindowOrganizerTests extends WindowTestsBase { final ITaskOrganizer organizer = registerMockOrganizer(); task.setTaskOrganizer(organizer); - verify(organizer).onTaskAppeared(any()); + verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); + task.removeImmediately(); verify(organizer).onTaskVanished(any()); @@ -147,11 +149,12 @@ public class WindowOrganizerTests extends WindowTestsBase { task.setTaskOrganizer(organizer); - verify(organizer, never()).onTaskAppeared(any()); + verify(organizer, never()) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); task.setHasBeenVisible(true); assertTrue(stack.getHasBeenVisible()); - verify(organizer).onTaskAppeared(any()); + verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); task.removeImmediately(); verify(organizer).onTaskVanished(any()); @@ -167,7 +170,8 @@ public class WindowOrganizerTests extends WindowTestsBase { // that even though a TaskOrganizer is set remove doesn't emit // a vanish callback, because we never emitted appear. task.setTaskOrganizer(organizer); - verify(organizer, never()).onTaskAppeared(any()); + verify(organizer, never()) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); task.removeImmediately(); verify(organizer, never()).onTaskVanished(any()); } @@ -180,10 +184,10 @@ public class WindowOrganizerTests extends WindowTestsBase { final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); task.setTaskOrganizer(organizer); - verify(organizer).onTaskAppeared(any()); + verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); task.setTaskOrganizer(organizer2); verify(organizer).onTaskVanished(any()); - verify(organizer2).onTaskAppeared(any()); + verify(organizer2).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); } @Test @@ -194,10 +198,10 @@ public class WindowOrganizerTests extends WindowTestsBase { final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - verify(organizer).onTaskAppeared(any()); + verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); stack.setWindowingMode(WINDOWING_MODE_PINNED); verify(organizer).onTaskVanished(any()); - verify(organizer2).onTaskAppeared(any()); + verify(organizer2).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); } @Test @@ -207,7 +211,8 @@ public class WindowOrganizerTests extends WindowTestsBase { final ITaskOrganizer organizer = registerMockOrganizer(); stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - verify(organizer, never()).onTaskAppeared(any()); + verify(organizer, never()) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); assertTrue(stack.isOrganized()); mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer); @@ -222,7 +227,7 @@ public class WindowOrganizerTests extends WindowTestsBase { final ITaskOrganizer organizer = registerMockOrganizer(); stack.setTaskOrganizer(organizer); - verify(organizer).onTaskAppeared(any()); + verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); assertTrue(stack.isOrganized()); stack.setTaskOrganizer(null); @@ -237,7 +242,7 @@ public class WindowOrganizerTests extends WindowTestsBase { final ITaskOrganizer organizer = registerMockOrganizer(); stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - verify(organizer).onTaskAppeared(any()); + verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); assertTrue(stack.isOrganized()); mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer); @@ -257,7 +262,8 @@ public class WindowOrganizerTests extends WindowTestsBase { // First organizer is registered, verify a task appears when changing windowing mode stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - verify(organizer, times(1)).onTaskAppeared(any()); + verify(organizer, times(1)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); assertTrue(stack.isOrganized()); // Now we replace the registration and1 verify the new organizer receives tasks @@ -265,7 +271,8 @@ public class WindowOrganizerTests extends WindowTestsBase { final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); // One each for task and task2 - verify(organizer2, times(2)).onTaskAppeared(any()); + verify(organizer2, times(2)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); verify(organizer2, times(0)).onTaskVanished(any()); // One for task verify(organizer).onTaskVanished(any()); @@ -274,11 +281,13 @@ public class WindowOrganizerTests extends WindowTestsBase { // Now we unregister the second one, the first one should automatically be reregistered // so we verify that it's now seeing changes. mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2); - verify(organizer, times(3)).onTaskAppeared(any()); + verify(organizer, times(3)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); verify(organizer2, times(2)).onTaskVanished(any()); stack3.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - verify(organizer, times(4)).onTaskAppeared(any()); + verify(organizer, times(4)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); verify(organizer2, times(2)).onTaskVanished(any()); assertTrue(stack3.isOrganized()); } @@ -291,7 +300,8 @@ public class WindowOrganizerTests extends WindowTestsBase { final Task task = createTask(stack); final Task task2 = createTask(stack); stack.setWindowingMode(WINDOWING_MODE_PINNED); - verify(organizer, times(1)).onTaskAppeared(any()); + verify(organizer, times(1)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); verify(organizer, times(1)).onTaskVanished(any()); @@ -304,7 +314,8 @@ public class WindowOrganizerTests extends WindowTestsBase { stack.setWindowingMode(WINDOWING_MODE_PINNED); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED); - verify(organizer, times(1)).onTaskAppeared(any()); + verify(organizer, times(1)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); } @Test @@ -459,7 +470,7 @@ public class WindowOrganizerTests extends WindowTestsBase { public void testTileAddRemoveChild() { ITaskOrganizer listener = new ITaskOrganizer.Stub() { @Override - public void onTaskAppeared(RunningTaskInfo taskInfo) { } + public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { } @Override public void onTaskVanished(RunningTaskInfo container) { } @@ -515,7 +526,7 @@ public class WindowOrganizerTests extends WindowTestsBase { final boolean[] called = {false}; ITaskOrganizer listener = new ITaskOrganizer.Stub() { @Override - public void onTaskAppeared(RunningTaskInfo taskInfo) { } + public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { } @Override public void onTaskVanished(RunningTaskInfo container) { } @@ -577,7 +588,7 @@ public class WindowOrganizerTests extends WindowTestsBase { final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>(); ITaskOrganizer listener = new ITaskOrganizer.Stub() { @Override - public void onTaskAppeared(RunningTaskInfo taskInfo) { } + public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { } @Override public void onTaskVanished(RunningTaskInfo container) { } @@ -804,7 +815,7 @@ public class WindowOrganizerTests extends WindowTestsBase { RunningTaskInfo mInfo; @Override - public void onTaskAppeared(RunningTaskInfo info) { + public void onTaskAppeared(RunningTaskInfo info, SurfaceControl leash) { mInfo = info; } @Override @@ -907,12 +918,14 @@ public class WindowOrganizerTests extends WindowTestsBase { task.setTaskOrganizer(organizer); // setHasBeenVisible was already called once by the set-up code. task.setHasBeenVisible(true); - verify(organizer, times(1)).onTaskAppeared(any()); + verify(organizer, times(1)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); task.setTaskOrganizer(null); verify(organizer, times(1)).onTaskVanished(any()); task.setTaskOrganizer(organizer); - verify(organizer, times(2)).onTaskAppeared(any()); + verify(organizer, times(2)) + .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class)); task.removeImmediately(); verify(organizer, times(2)).onTaskVanished(any()); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 6a64d1c976c4..94c204ab0fe0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -52,13 +52,9 @@ import android.view.WindowManager; import com.android.server.AttributeCache; -import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; -import java.util.HashSet; -import java.util.LinkedList; - /** * Common base class for window manager unit test classes. * @@ -85,7 +81,6 @@ class WindowTestsBase extends SystemServiceTestsBase { WindowState mAppWindow; WindowState mChildAppWindowAbove; WindowState mChildAppWindowBelow; - HashSet<WindowState> mCommonWindows; /** * Spied {@link Transaction} class than can be used to verify calls. @@ -115,7 +110,6 @@ class WindowTestsBase extends SystemServiceTestsBase { mDisplayContent = createNewDisplay(true /* supportIme */); // Set-up some common windows. - mCommonWindows = new HashSet<>(); synchronized (mWm.mGlobalLock) { mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow"); mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow"); @@ -151,48 +145,9 @@ class WindowTestsBase extends SystemServiceTestsBase { // Called before display is created. } - @After - public void tearDownBase() { - // If @After throws an exception, the error isn't logged. This will make sure any failures - // in the tear down are clear. This can be removed when b/37850063 is fixed. - try { - // Test may schedule to perform surface placement or other messages. Wait until a - // stable state to clean up for consistency. - waitUntilHandlersIdle(); - - final LinkedList<WindowState> nonCommonWindows = new LinkedList<>(); - - synchronized (mWm.mGlobalLock) { - mWm.mRoot.forAllWindows(w -> { - if (!mCommonWindows.contains(w)) { - nonCommonWindows.addLast(w); - } - }, true /* traverseTopToBottom */); - - while (!nonCommonWindows.isEmpty()) { - nonCommonWindows.pollLast().removeImmediately(); - } - - // Remove app transition & window freeze timeout callbacks to prevent unnecessary - // actions after test. - mWm.getDefaultDisplayContentLocked().mAppTransition - .removeAppTransitionTimeoutCallbacks(); - mWm.mH.removeMessages(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT); - mDisplayContent.mInputMethodTarget = null; - } - - // Cleaned up everything in Handler. - cleanupWindowManagerHandlers(); - } catch (Exception e) { - Log.e(TAG, "Failed to tear down test", e); - throw e; - } - } - private WindowState createCommonWindow(WindowState parent, int type, String name) { synchronized (mWm.mGlobalLock) { final WindowState win = createWindow(parent, type, name); - mCommonWindows.add(win); // Prevent common windows from been IMe targets win.mAttrs.flags |= FLAG_NOT_FOCUSABLE; return win; diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index 535d53eeef71..23a097eb0c7c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -136,7 +136,7 @@ public class WindowTokenTests extends WindowTestsBase { } @Test - public void testClearFixedRotationTransform() { + public void testFinishFixedRotationTransform() { final WindowToken appToken = mAppWindow.mToken; final WindowToken wallpaperToken = mWallpaperWindow.mToken; final Configuration config = new Configuration(mDisplayContent.getConfiguration()); @@ -152,7 +152,7 @@ public class WindowTokenTests extends WindowTestsBase { assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation()); // The display doesn't rotate, the transformation will be canceled. - mAppWindow.mToken.clearFixedRotationTransform(null /* applyDisplayRotation */); + mAppWindow.mToken.finishFixedRotationTransform(); // The window tokens should restore to the original rotation. assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation()); diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java index e5497a2313d1..233e147c5904 100644 --- a/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java @@ -27,10 +27,12 @@ import android.graphics.GraphicBuffer; import android.graphics.Matrix; import android.graphics.PointF; import android.view.Surface; +import android.platform.test.annotations.Presubmit; import org.junit.Before; import org.junit.Test; +@Presubmit public class RotationAnimationUtilsTest { private static final int BITMAP_HEIGHT = 100; diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 0983db6d9663..eb553d3e8af3 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -2215,6 +2215,7 @@ public class TelecomManager { * @hide */ @SystemApi + @TestApi @NonNull public Intent createLaunchEmergencyDialerIntent(@Nullable String number) { ITelecomService service = getTelecomService(); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index d2de19aaf89a..477bb1fc19dc 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3050,19 +3050,95 @@ public class CarrierConfigManager { public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string"; /** - * Timeout in seconds for displaying 5G icon, default value is 0 which means the timer is - * disabled. + * This configuration allows the system UI to determine how long to continue to display 5G icons + * when the device switches between different 5G scenarios. + * + * There are seven 5G scenarios: + * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using + * millimeter wave. + * 2. connected: device currently connected to 5G cell as the secondary cell but not using + * millimeter wave. + * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability (not necessary + * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC + * currently in IDLE state. + * 4. not_restricted_rrc_con: device camped on a network that has 5G capability (not necessary + * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC + * currently in CONNECTED state. + * 5. restricted: device camped on a network that has 5G capability (not necessary to connect a + * 5G cell as a secondary cell) but the use of 5G is restricted. + * 6. legacy: device is not camped on a network that has 5G capability + * 7. any: any of the above scenarios + * + * The configured string contains various timer rules separated by a semicolon. + * Each rule will have three items: prior 5G scenario, current 5G scenario, and grace period + * in seconds before changing the icon. When the 5G state changes from the prior to the current + * 5G scenario, the system UI will continue to show the icon for the prior 5G scenario (defined + * in {@link #KEY_5G_ICON_CONFIGURATION_STRING}) for the amount of time specified by the grace + * period. If the prior 5G scenario is reestablished, the timer will reset and start again if + * the UE changes 5G scenarios again. Defined states (5G scenarios #1-5) take precedence over + * 'any' (5G scenario #6), and unspecified transitions have a default grace period of 0. + * The order of rules in the configuration determines the priority (the first applicable timer + * rule will be used). + * + * Here is an example: "connected_mmwave,connected,30;connected_mmwave,any,10;connected,any,10" + * This configuration defines 3 timers: + * 1. When UE goes from 'connected_mmwave' to 'connected', system UI will continue to display + * the 5G icon for 'connected_mmwave' for 30 seconds. + * 2. When UE goes from 'connected_mmwave' to any other state (except for connected, since + * rule 1 would be used instead), system UI will continue to display the 5G icon for + * 'connected_mmwave' for 10 seconds. + * 3. When UE goes from 'connected' to any other state, system UI will continue to display the + * 5G icon for 'connected' for 10 seconds. + * + * @hide + */ + public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING = + "5g_icon_display_grace_period_string"; + + /** + * This configuration extends {@link #KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING} to allow the + * system UI to continue displaying 5G icons after the initial timer expires. + * + * There are seven 5G scenarios: + * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using + * millimeter wave. + * 2. connected: device currently connected to 5G cell as the secondary cell but not using + * millimeter wave. + * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability (not necessary + * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC + * currently in IDLE state. + * 4. not_restricted_rrc_con: device camped on a network that has 5G capability (not necessary + * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC + * currently in CONNECTED state. + * 5. restricted: device camped on a network that has 5G capability (not necessary to connect a + * 5G cell as a secondary cell) but the use of 5G is restricted. + * 6. legacy: device is not camped on a network that has 5G capability + * 7. any: any of the above scenarios + * + * The configured string contains various timer rules separated by a semicolon. + * Each rule will have three items: primary 5G scenario, secondary 5G scenario, and + * grace period in seconds before changing the icon. When the timer for the primary 5G timer + * expires, the system UI will continue to show the icon for the primary 5G scenario (defined + * in {@link #KEY_5G_ICON_CONFIGURATION_STRING}) for the amount of time specified by the grace + * period. If the primary 5G scenario is reestablished, the timers will reset and the system UI + * will continue to display the icon for the primary 5G scenario without interruption. If the + * secondary 5G scenario is lost, the timer will reset and the icon will reflect the true state. + * Defined states (5G scenarios #1-5) take precedence over 'any' (5G scenario #6), and + * unspecified transitions have a default grace period of 0. The order of rules in the + * configuration determines the priority (the first applicable timer rule will be used). * - * System UI will show the 5G icon and start a timer with the timeout from this config when the - * device connects to a 5G cell. System UI stops displaying 5G icon when both the device - * disconnects from 5G cell and the timer is expired. + * Here is an example: "connected,not_restricted_rrc_idle,30" + * This configuration defines a secondary timer that extends the primary 'connected' timer. + * When the primary 'connected' timer expires while the UE is in the 'not_restricted_rrc_idle' + * 5G state, system UI will continue to display the 5G icon for 'connected' for 30 seconds. + * If the 5G state returns to 'connected', the timer will be reset without change to the icon, + * and if the 5G state changes to neither 'connected' not 'not_restricted_rrc_idle', the icon + * will change to reflect the true state. * - * If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next - * lost. Allows us to momentarily lose 5G without blinking the icon. * @hide */ - public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT = - "5g_icon_display_grace_period_sec_int"; + public static final String KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING = + "5g_icon_display_secondary_grace_period_string"; /** * Controls time in milliseconds until DcTracker reevaluates 5G connection state. @@ -4129,7 +4205,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_BANDWIDTH_STRING_ARRAY, new String[]{ "GPRS:24,24", "EDGE:70,18", "UMTS:115,115", "CDMA-IS95A:14,14", "CDMA-IS95B:14,14", "1xRTT:30,30", "EvDo-rev.0:750,48", "EvDo-rev.A:950,550", "HSDPA:4300,620", - "HSUPA:4300,1800", "HSPA:4300,1800", "EvDo-rev.B:1500,550:", "eHRPD:750,48", + "HSUPA:4300,1800", "HSPA:4300,1800", "EvDo-rev.B:1500,550", "eHRPD:750,48", "HSPAP:13000,3400", "TD-SCDMA:115,115", "LTE:30000,15000", "NR_NSA:47000,15000", "NR_NSA_MMWAVE:145000,15000", "NR_SA:145000,15000"}); sDefaults.putBoolean(KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPSTREAM_BOOL, false); @@ -4148,7 +4224,8 @@ public class CarrierConfigManager { sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING, "connected_mmwave:5G,connected:5G,not_restricted_rrc_idle:5G," + "not_restricted_rrc_con:5G"); - sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0); + sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, ""); + sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, ""); /* Default value is 1 hour. */ sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000); sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false); diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 0e61efac77ec..07d71d0ad7f9 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -398,6 +398,7 @@ public class ServiceState implements Parcelable { * @hide */ @NonNull + @UnsupportedAppUsage public static ServiceState newFromBundle(@NonNull Bundle m) { ServiceState ret; ret = new ServiceState(); @@ -1315,6 +1316,7 @@ public class ServiceState implements Parcelable { * @hide * */ + @UnsupportedAppUsage public void fillInNotifierBundle(@NonNull Bundle m) { m.putParcelable(EXTRA_SERVICE_STATE, this); // serviceState already consists of below entries. diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 801d63905af9..45dc7afc3dc0 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -135,29 +135,28 @@ public class SubscriptionManager { public static final String CACHE_KEY_DEFAULT_SUB_ID_PROPERTY = "cache_key.telephony.get_default_sub_id"; - private static final int DEFAULT_SUB_ID_CACHE_SIZE = 1; + /** @hide */ + public static final String CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY = + "cache_key.telephony.get_default_data_sub_id"; + + private static final int MAX_CACHE_SIZE = 4; private static PropertyInvalidatedCache<Void, Integer> sDefaultSubIdCache = new PropertyInvalidatedCache<Void, Integer>( - DEFAULT_SUB_ID_CACHE_SIZE, - CACHE_KEY_DEFAULT_SUB_ID_PROPERTY) { - @Override - protected Integer recompute(Void query) { - int subId = INVALID_SUBSCRIPTION_ID; + MAX_CACHE_SIZE, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY) { + @Override + protected Integer recompute(Void query) { + return getDefaultSubscriptionIdInternal(); + }}; - try { - ISub iSub = TelephonyManager.getSubscriptionService(); - if (iSub != null) { - subId = iSub.getDefaultSubId(); - } - } catch (RemoteException ex) { - // ignore it - } + private static PropertyInvalidatedCache<Void, Integer> sDefaultDataSubIdCache = + new PropertyInvalidatedCache<Void, Integer>( + MAX_CACHE_SIZE, CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY) { + @Override + protected Integer recompute(Void query) { + return getDefaultDataSubscriptionIdInternal(); + }}; - if (VDBG) logd("getDefaultSubId=" + subId); - return subId; - } - }; /** * Generates a content {@link Uri} used to receive updates on simInfo change * on the given subscriptionId @@ -1871,6 +1870,22 @@ public class SubscriptionManager { return sDefaultSubIdCache.query(null); } + private static int getDefaultSubscriptionIdInternal() { + int subId = INVALID_SUBSCRIPTION_ID; + + try { + ISub iSub = TelephonyManager.getSubscriptionService(); + if (iSub != null) { + subId = iSub.getDefaultSubId(); + } + } catch (RemoteException ex) { + // ignore it + } + + if (VDBG) logd("getDefaultSubId=" + subId); + return subId; + } + /** * Returns the system's default voice subscription id. * @@ -2021,6 +2036,10 @@ public class SubscriptionManager { * @return the default data subscription Id. */ public static int getDefaultDataSubscriptionId() { + return sDefaultDataSubIdCache.query(null); + } + + private static int getDefaultDataSubscriptionIdInternal() { int subId = INVALID_SUBSCRIPTION_ID; try { @@ -3296,6 +3315,11 @@ public class SubscriptionManager { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SUB_ID_PROPERTY); } + /** @hide */ + public static void invalidateDefaultDataSubIdCaches() { + PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY); + } + /** * Clears all process-local binder caches. * @@ -3303,5 +3327,6 @@ public class SubscriptionManager { */ public static void clearCaches() { sDefaultSubIdCache.clear(); + sDefaultDataSubIdCache.clear(); } } diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 7488a1aec0e5..2edb564cc950 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -269,10 +269,10 @@ public class EuiccManager { * only contains {@link #OPERATION_DOWNLOAD} and ErrorCode is 0 implies this is an unknown * Download error. * - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE} + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE */ public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE"; @@ -552,7 +552,7 @@ public class EuiccManager { /** * List of OperationCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}'s - * value, an integer. @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * value, an integer. @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details * * @hide */ @@ -575,44 +575,44 @@ public class EuiccManager { /** * Internal system error. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_SYSTEM = 1; /** * SIM slot error. Failed to switch slot, failed to access the physical slot etc. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_SIM_SLOT = 2; /** * eUICC card error. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_EUICC_CARD = 3; /** * Generic switching profile error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_SWITCH = 4; /** * Download profile error. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_DOWNLOAD = 5; /** * Subscription's metadata error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_METADATA = 6; /** * eUICC returned an error defined in GSMA (SGP.22 v2.2) while running one of the ES10x * functions. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_EUICC_GSMA = 7; @@ -620,13 +620,13 @@ public class EuiccManager { * The exception of failing to execute an APDU command. It can be caused by an error * happening on opening the basic or logical channel, or the response of the APDU command is * not success (0x9000). - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_APDU = 8; /** * SMDX(SMDP/SMDS) error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_SMDX = 9; @@ -655,19 +655,19 @@ public class EuiccManager { * Thus the integer stored in {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} is * 0xA8B1051(176885841) * - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10; /** * HTTP error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int OPERATION_HTTP = 11; /** * List of ErrorCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details * @hide */ @Retention(RetentionPolicy.SOURCE) @@ -695,56 +695,56 @@ public class EuiccManager { /** * Operation such as downloading/switching to another profile failed due to device being * carrier locked. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_CARRIER_LOCKED = 10000; /** * The activation code(SGP.22 v2.2 section[4.1]) is invalid. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_INVALID_ACTIVATION_CODE = 10001; /** * The confirmation code(SGP.22 v2.2 section[4.7]) is invalid. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002; /** * The profile's carrier is incompatible with the LPA. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_INCOMPATIBLE_CARRIER = 10003; /** * There is no more space available on the eUICC for new profiles. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004; /** * Timed out while waiting for an operation to complete. i.e restart, disable, * switch reset etc. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_TIME_OUT = 10005; /** * eUICC is missing or defective on the device. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_EUICC_MISSING = 10006; /** * The eUICC card(hardware) version is incompatible with the software - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_UNSUPPORTED_VERSION = 10007; /** * No SIM card is available in the device. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_SIM_MISSING = 10008; @@ -754,52 +754,52 @@ public class EuiccManager { * 2. GSMA(.22 v2.2) Profile Install Result - installFailedDueToDataMismatch * 3. operation was interrupted * 4. SIMalliance error in PEStatus(SGP.22 v2.2 section 2.5.6.1) - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_INSTALL_PROFILE = 10009; /** * Failed to load profile onto eUICC due to Profile Poicly Rules. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_DISALLOWED_BY_PPR = 10010; /** * Address is missing e.g SMDS/SMDP address is missing. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_ADDRESS_MISSING = 10011; /** * Certificate needed for authentication is not valid or missing. E.g SMDP/SMDS authentication * failed. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_CERTIFICATE_ERROR = 10012; /** * No profiles available. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_NO_PROFILES_AVAILABLE = 10013; /** * Failure to create a connection. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_CONNECTION_ERROR = 10014; /** * Response format is invalid. e.g SMDP/SMDS response contains invalid json, header or/and ASN1. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_INVALID_RESPONSE = 10015; /** * The operation is currently busy, try again later. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_OPERATION_BUSY = 10016; diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index 7ff8735d7b73..0b25d6f8275b 100644 --- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -430,7 +430,6 @@ public class MmTelFeature extends ImsFeature { /** * @param listener A {@link Listener} used when the MmTelFeature receives an incoming call and * notifies the framework. - * @hide */ private void setListener(IImsMmTelListener listener) { synchronized (mLock) { @@ -442,6 +441,16 @@ public class MmTelFeature extends ImsFeature { } /** + * @return the listener associated with this MmTelFeature. May be null if it has not been set + * by the framework yet. + */ + private IImsMmTelListener getListener() { + synchronized (mLock) { + return mListener; + } + } + + /** * The current capability status that this MmTelFeature has defined is available. This * configuration will be used by the platform to figure out which capabilities are CURRENTLY * available to be used. @@ -489,15 +498,14 @@ public class MmTelFeature extends ImsFeature { throw new IllegalArgumentException("ImsCallSessionImplBase and Bundle can not be " + "null."); } - synchronized (mLock) { - if (mListener == null) { - throw new IllegalStateException("Session is not available."); - } - try { - mListener.onIncomingCall(c.getServiceImpl(), extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } + IImsMmTelListener listener = getListener(); + if (listener == null) { + throw new IllegalStateException("Session is not available."); + } + try { + listener.onIncomingCall(c.getServiceImpl(), extras); + } catch (RemoteException e) { + throw new RuntimeException(e); } } @@ -516,15 +524,14 @@ public class MmTelFeature extends ImsFeature { throw new IllegalArgumentException("ImsCallProfile and ImsReasonInfo must not be " + "null."); } - synchronized (mLock) { - if (mListener == null) { - throw new IllegalStateException("Session is not available."); - } - try { - mListener.onRejectedCall(callProfile, reason); - } catch (RemoteException e) { - throw new RuntimeException(e); - } + IImsMmTelListener listener = getListener(); + if (listener == null) { + throw new IllegalStateException("Session is not available."); + } + try { + listener.onRejectedCall(callProfile, reason); + } catch (RemoteException e) { + throw new RuntimeException(e); } } @@ -533,15 +540,14 @@ public class MmTelFeature extends ImsFeature { * @hide */ public final void notifyIncomingCallSession(IImsCallSession c, Bundle extras) { - synchronized (mLock) { - if (mListener == null) { - throw new IllegalStateException("Session is not available."); - } - try { - mListener.onIncomingCall(c, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } + IImsMmTelListener listener = getListener(); + if (listener == null) { + throw new IllegalStateException("Session is not available."); + } + try { + listener.onIncomingCall(c, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); } } @@ -552,15 +558,14 @@ public class MmTelFeature extends ImsFeature { */ @SystemApi @TestApi public final void notifyVoiceMessageCountUpdate(int count) { - synchronized (mLock) { - if (mListener == null) { - throw new IllegalStateException("Session is not available."); - } - try { - mListener.onVoiceMessageCountUpdate(count); - } catch (RemoteException e) { - throw new RuntimeException(e); - } + IImsMmTelListener listener = getListener(); + if (listener == null) { + throw new IllegalStateException("Session is not available."); + } + try { + listener.onVoiceMessageCountUpdate(count); + } catch (RemoteException e) { + throw new RuntimeException(e); } } diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 18e25921555a..76fc4f7d0519 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -109,11 +109,10 @@ public class DctConstants { public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49; public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50; public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51; - public static final int EVENT_SERVICE_STATE_CHANGED = BASE + 52; - public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53; - public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54; - public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 55; - public static final int EVENT_SIM_STATE_UPDATED = BASE + 56; + public static final int EVENT_TELEPHONY_DISPLAY_INFO_CHANGED = BASE + 52; + public static final int EVENT_NR_TIMER_WATCHDOG = BASE + 53; + public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 54; + public static final int EVENT_SIM_STATE_UPDATED = BASE + 55; /***** Constants *****/ diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java index 86c3fa0fe034..073ae30aaf1a 100644 --- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java +++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java @@ -18,32 +18,27 @@ package com.android.test.taskembed; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; -import android.app.ActivityManager; import android.app.Activity; +import android.app.ActivityManager; import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.graphics.Rect; import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; import android.view.Gravity; import android.view.MotionEvent; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.View; import android.view.ViewGroup; -import android.window.ITaskOrganizer; -import android.window.IWindowContainerTransactionCallback; +import android.widget.LinearLayout; import android.window.TaskOrganizer; import android.window.WindowContainerTransaction; -import android.widget.LinearLayout; import android.window.WindowContainerTransactionCallback; -import android.window.WindowOrganizer; public class TaskOrganizerMultiWindowTest extends Activity { - class SplitLayout extends LinearLayout implements View.OnTouchListener { + static class SplitLayout extends LinearLayout implements View.OnTouchListener { View mView1; View mView2; View mDividerView; @@ -99,8 +94,8 @@ public class TaskOrganizerMultiWindowTest extends Activity { class ResizingTaskView extends TaskView { final Intent mIntent; boolean launched = false; - ResizingTaskView(Context c, TaskOrganizer o, int windowingMode, Intent i) { - super(c, o, windowingMode); + ResizingTaskView(Context c, Intent i) { + super(c); mIntent = i; } @@ -125,9 +120,9 @@ public class TaskOrganizerMultiWindowTest extends Activity { } } - TaskView mTaskView1; - TaskView mTaskView2; - boolean gotFirstTask = false; + private TaskView mTaskView1; + private TaskView mTaskView2; + private boolean mGotFirstTask = false; class Organizer extends TaskOrganizer { private int receivedTransactions = 0; @@ -146,17 +141,17 @@ public class TaskOrganizerMultiWindowTest extends Activity { }; @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo ti) { - if (!gotFirstTask) { - mTaskView1.reparentTask(ti.token); - gotFirstTask = true; + public void onTaskAppeared(ActivityManager.RunningTaskInfo ti, SurfaceControl leash) { + if (!mGotFirstTask) { + mTaskView1.reparentTask(ti.token, leash); + mGotFirstTask = true; } else { - mTaskView2.reparentTask(ti.token); + mTaskView2.reparentTask(ti.token, leash); } } } - Organizer mOrganizer = new Organizer(); + private Organizer mOrganizer = new Organizer(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -164,27 +159,31 @@ public class TaskOrganizerMultiWindowTest extends Activity { mOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW); - mTaskView1 = new ResizingTaskView(this, mOrganizer, WINDOWING_MODE_MULTI_WINDOW, - makeSettingsIntent()); - mTaskView2 = new ResizingTaskView(this, mOrganizer, WINDOWING_MODE_MULTI_WINDOW, - makeContactsIntent()); + mTaskView1 = new ResizingTaskView(this, makeSettingsIntent()); + mTaskView2 = new ResizingTaskView(this, makeContactsIntent()); View splitView = new SplitLayout(this, mTaskView1, mTaskView2); setContentView(splitView); } + @Override + protected void onDestroy() { + super.onDestroy(); + mOrganizer.unregisterOrganizer(); + } + private void addFlags(Intent intent) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION); } - Intent makeSettingsIntent() { + private Intent makeSettingsIntent() { Intent intent = new Intent(); intent.setAction(android.provider.Settings.ACTION_SETTINGS); addFlags(intent); return intent; } - Intent makeContactsIntent() { + private Intent makeContactsIntent() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_APP_CONTACTS); @@ -192,14 +191,14 @@ public class TaskOrganizerMultiWindowTest extends Activity { return intent; } - Bundle makeLaunchOptions(int width, int height) { + private Bundle makeLaunchOptions(int width, int height) { ActivityOptions o = ActivityOptions.makeBasic(); o.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW); o.setLaunchBounds(new Rect(0, 0, width, height)); return o.toBundle(); } - void launchOrganizedActivity(Intent i, int width, int height) { + private void launchOrganizedActivity(Intent i, int width, int height) { startActivity(i, makeLaunchOptions(width, height)); } } diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java index 2a1aa2e1de65..8fc5c5d78b60 100644 --- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java +++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java @@ -23,21 +23,22 @@ import android.app.Service; import android.content.Intent; import android.graphics.Rect; import android.os.IBinder; +import android.view.SurfaceControl; import android.view.ViewGroup; -import android.window.TaskOrganizer; -import android.window.WindowContainerTransaction; import android.view.WindowManager; import android.widget.FrameLayout; +import android.window.TaskOrganizer; +import android.window.WindowContainerTransaction; public class TaskOrganizerPipTest extends Service { - static final int PIP_WIDTH = 640; - static final int PIP_HEIGHT = 360; + private static final int PIP_WIDTH = 640; + private static final int PIP_HEIGHT = 360; - TaskView mTaskView; + private TaskView mTaskView; class Organizer extends TaskOrganizer { - public void onTaskAppeared(ActivityManager.RunningTaskInfo ti) { - mTaskView.reparentTask(ti.token); + public void onTaskAppeared(ActivityManager.RunningTaskInfo ti, SurfaceControl leash) { + mTaskView.reparentTask(ti.token, leash); final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.scheduleFinishEnterPip(ti.token, new Rect(0, 0, PIP_WIDTH, PIP_HEIGHT)); @@ -45,7 +46,7 @@ public class TaskOrganizerPipTest extends Service { } } - Organizer mOrganizer = new Organizer(); + private Organizer mOrganizer = new Organizer(); @Override public IBinder onBind(Intent intent) { @@ -66,7 +67,7 @@ public class TaskOrganizerPipTest extends Service { FrameLayout layout = new FrameLayout(this); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(PIP_WIDTH, PIP_HEIGHT); - mTaskView = new TaskView(this, mOrganizer, WINDOWING_MODE_PINNED); + mTaskView = new TaskView(this); layout.addView(mTaskView, lp); WindowManager wm = getSystemService(WindowManager.class); @@ -76,5 +77,6 @@ public class TaskOrganizerPipTest extends Service { @Override public void onDestroy() { super.onDestroy(); + mOrganizer.unregisterOrganizer(); } } diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskView.java b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskView.java index aa041f22a46e..208018c2543a 100644 --- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskView.java +++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskView.java @@ -16,34 +16,27 @@ package com.android.test.taskembed; -import android.app.ActivityTaskManager; import android.content.Context; -import android.window.TaskOrganizer; -import android.window.WindowContainerToken; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; -import android.window.ITaskOrganizer; +import android.window.WindowContainerToken; /** * Simple SurfaceView wrapper which registers a TaskOrganizer * after it's Surface is ready. */ class TaskView extends SurfaceView implements SurfaceHolder.Callback { - final TaskOrganizer mTaskOrganizer; - final int mWindowingMode; WindowContainerToken mWc; + private SurfaceControl mLeash; - boolean mSurfaceCreated = false; - boolean mNeedsReparent; + private boolean mSurfaceCreated = false; + private boolean mNeedsReparent; - TaskView(Context c, TaskOrganizer o, int windowingMode) { + TaskView(Context c) { super(c); getHolder().addCallback(this); setZOrderOnTop(true); - - mTaskOrganizer = o; - mWindowingMode = windowingMode; } @Override @@ -63,27 +56,25 @@ class TaskView extends SurfaceView implements SurfaceHolder.Callback { public void surfaceDestroyed(SurfaceHolder holder) { } - void reparentTask(WindowContainerToken wc) { + void reparentTask(WindowContainerToken wc, SurfaceControl leash) { mWc = wc; - if (mSurfaceCreated == false) { + mLeash = leash; + if (!mSurfaceCreated) { mNeedsReparent = true; } else { reparentLeash(); } } - void reparentLeash() { + private void reparentLeash() { SurfaceControl.Transaction t = new SurfaceControl.Transaction(); - SurfaceControl leash = null; - try { - leash = mWc.getLeash(); - } catch (Exception e) { - // System server died.. oh well + if (mLeash == null) { + return; } - t.reparent(leash, getSurfaceControl()) - .setPosition(leash, 0, 0) - .show(leash) + t.reparent(mLeash, getSurfaceControl()) + .setPosition(mLeash, 0, 0) + .show(mLeash) .apply(); } } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index a478e68c7dba..a992778fd45f 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -144,6 +144,7 @@ import android.net.ConnectivityManager.PacketKeepalive; import android.net.ConnectivityManager.PacketKeepaliveCallback; import android.net.ConnectivityManager.TooManyRequestsException; import android.net.ConnectivityThread; +import android.net.DataStallReportParcelable; import android.net.IConnectivityDiagnosticsCallback; import android.net.IDnsResolver; import android.net.IIpConnectivityMetrics; @@ -170,6 +171,7 @@ import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; import android.net.NetworkState; +import android.net.NetworkTestResultParcelable; import android.net.NetworkUtils; import android.net.ProxyInfo; import android.net.ResolverParamsParcel; @@ -196,7 +198,6 @@ import android.os.Looper; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; -import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; @@ -580,14 +581,6 @@ public class ConnectivityServiceTest { } private class TestNetworkAgentWrapper extends NetworkAgentWrapper { - private static final int VALIDATION_RESULT_BASE = NETWORK_VALIDATION_PROBE_DNS - | NETWORK_VALIDATION_PROBE_HTTP - | NETWORK_VALIDATION_PROBE_HTTPS; - private static final int VALIDATION_RESULT_VALID = VALIDATION_RESULT_BASE - | NETWORK_VALIDATION_RESULT_VALID; - private static final int VALIDATION_RESULT_PARTIAL = VALIDATION_RESULT_BASE - | NETWORK_VALIDATION_PROBE_FALLBACK - | NETWORK_VALIDATION_RESULT_PARTIAL; private static final int VALIDATION_RESULT_INVALID = 0; private static final long DATA_STALL_TIMESTAMP = 10L; @@ -595,12 +588,10 @@ public class ConnectivityServiceTest { private INetworkMonitor mNetworkMonitor; private INetworkMonitorCallbacks mNmCallbacks; - private int mNmValidationResult = VALIDATION_RESULT_BASE; + private int mNmValidationResult = VALIDATION_RESULT_INVALID; private int mProbesCompleted; private int mProbesSucceeded; private String mNmValidationRedirectUrl = null; - private PersistableBundle mValidationExtras = PersistableBundle.EMPTY; - private PersistableBundle mDataStallExtras = PersistableBundle.EMPTY; private boolean mNmProvNotificationRequested = false; private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); @@ -668,8 +659,13 @@ public class ConnectivityServiceTest { } mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); - mNmCallbacks.notifyNetworkTestedWithExtras( - mNmValidationResult, mNmValidationRedirectUrl, TIMESTAMP, mValidationExtras); + final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); + p.result = mNmValidationResult; + p.probesAttempted = mProbesCompleted; + p.probesSucceeded = mProbesSucceeded; + p.redirectUrl = mNmValidationRedirectUrl; + p.timestampMillis = TIMESTAMP; + mNmCallbacks.notifyNetworkTestedWithExtras(p); if (mNmValidationRedirectUrl != null) { mNmCallbacks.showProvisioningNotification( @@ -751,9 +747,9 @@ public class ConnectivityServiceTest { } void setNetworkValid(boolean isStrictMode) { - mNmValidationResult = VALIDATION_RESULT_VALID; + mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; mNmValidationRedirectUrl = null; - int probesSucceeded = VALIDATION_RESULT_BASE & ~NETWORK_VALIDATION_PROBE_HTTP; + int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; if (isStrictMode) { probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; } @@ -765,8 +761,9 @@ public class ConnectivityServiceTest { void setNetworkInvalid(boolean isStrictMode) { mNmValidationResult = VALIDATION_RESULT_INVALID; mNmValidationRedirectUrl = null; - int probesCompleted = VALIDATION_RESULT_BASE; - int probesSucceeded = VALIDATION_RESULT_INVALID; + int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS + | NETWORK_VALIDATION_PROBE_HTTP; + int probesSucceeded = 0; // If the isStrictMode is true, it means the network is invalid when NetworkMonitor // tried to validate the private DNS but failed. if (isStrictMode) { @@ -782,7 +779,7 @@ public class ConnectivityServiceTest { mNmValidationRedirectUrl = redirectUrl; // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. - int probesCompleted = VALIDATION_RESULT_BASE & ~NETWORK_VALIDATION_PROBE_HTTPS; + int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; int probesSucceeded = VALIDATION_RESULT_INVALID; if (isStrictMode) { probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; @@ -791,18 +788,20 @@ public class ConnectivityServiceTest { } void setNetworkPartial() { - mNmValidationResult = VALIDATION_RESULT_PARTIAL; + mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; mNmValidationRedirectUrl = null; - int probesCompleted = VALIDATION_RESULT_BASE; - int probesSucceeded = VALIDATION_RESULT_BASE & ~NETWORK_VALIDATION_PROBE_HTTPS; + int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS + | NETWORK_VALIDATION_PROBE_FALLBACK; + int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; setProbesStatus(probesCompleted, probesSucceeded); } void setNetworkPartialValid(boolean isStrictMode) { setNetworkPartial(); - mNmValidationResult |= VALIDATION_RESULT_VALID; - int probesCompleted = VALIDATION_RESULT_BASE; - int probesSucceeded = VALIDATION_RESULT_BASE & ~NETWORK_VALIDATION_PROBE_HTTPS; + mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; + int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS + | NETWORK_VALIDATION_PROBE_HTTP; + int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; // Suppose the partial network cannot pass the private DNS validation as well, so only // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. if (isStrictMode) { @@ -838,8 +837,10 @@ public class ConnectivityServiceTest { } void notifyDataStallSuspected() throws Exception { - mNmCallbacks.notifyDataStallSuspected( - DATA_STALL_TIMESTAMP, DATA_STALL_DETECTION_METHOD, mDataStallExtras); + final DataStallReportParcelable p = new DataStallReportParcelable(); + p.detectionMethod = DATA_STALL_DETECTION_METHOD; + p.timestampMillis = DATA_STALL_TIMESTAMP; + mNmCallbacks.notifyDataStallSuspected(p); } } diff --git a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java index 28785f7c9726..3aafe0b075f2 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java @@ -41,6 +41,7 @@ abstract class NetworkStatsBaseTest { static final String TEST_IFACE = "test0"; static final String TEST_IFACE2 = "test1"; static final String TUN_IFACE = "test_nss_tun0"; + static final String TUN_IFACE2 = "test_nss_tun1"; static final int UID_RED = 1001; static final int UID_BLUE = 1002; @@ -107,10 +108,14 @@ abstract class NetworkStatsBaseTest { assertEquals("unexpected operations", operations, entry.operations); } - VpnInfo createVpnInfo(String[] underlyingIfaces) { + static VpnInfo createVpnInfo(String[] underlyingIfaces) { + return createVpnInfo(TUN_IFACE, underlyingIfaces); + } + + static VpnInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) { VpnInfo info = new VpnInfo(); info.ownerUid = UID_VPN; - info.vpnIface = TUN_IFACE; + info.vpnIface = vpnIface; info.underlyingIfaces = underlyingIfaces; return info; } diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java index a21f5095c746..4473492d7972 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java @@ -104,7 +104,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnRewriteTrafficThroughItself() throws Exception { + public void testVpnRewriteTrafficThroughItself() throws Exception { VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; mFactory.updateVpnInfos(vpnInfos); @@ -133,7 +133,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithClat() throws Exception { + public void testVpnWithClat() throws Exception { VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})}; mFactory.updateVpnInfos(vpnInfos); mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE); @@ -166,7 +166,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithOneUnderlyingIface() throws Exception { + public void testVpnWithOneUnderlyingIface() throws Exception { VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; mFactory.updateVpnInfos(vpnInfos); @@ -189,7 +189,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception { + public void testVpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception { // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE). VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; mFactory.updateVpnInfos(vpnInfos); @@ -217,7 +217,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithOneUnderlyingIface_withCompression() throws Exception { + public void testVpnWithOneUnderlyingIface_withCompression() throws Exception { // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE). VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; mFactory.updateVpnInfos(vpnInfos); @@ -238,7 +238,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception { + public void testVpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception { // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set. // Additionally, VPN is duplicating traffic across both WiFi and Cell. @@ -264,7 +264,47 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception { + public void testConcurrentVpns() throws Exception { + // Assume two VPNs are connected on two different network interfaces. VPN1 is using + // TEST_IFACE and VPN2 is using TEST_IFACE2. + final VpnInfo[] vpnInfos = new VpnInfo[] { + createVpnInfo(TUN_IFACE, new String[] {TEST_IFACE}), + createVpnInfo(TUN_IFACE2, new String[] {TEST_IFACE2})}; + mFactory.updateVpnInfos(vpnInfos); + + // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption + // overhead per packet): + // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED + // over VPN1. + // 700 bytes (70 packets) were sent, and 3000 bytes (300 packets) were received by UID_RED + // over VPN2. + // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE + // over VPN1. + // 250 bytes (25 packets) were sent, and 500 bytes (50 packets) were received by UID_BLUE + // over VPN2. + // VPN1 sent 1650 bytes (150 packets), and received 3300 (300 packets) over TEST_IFACE. + // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes + // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN. + // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes + // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN. + // VPN2 sent 1045 bytes (95 packets), and received 3850 (350 packets) over TEST_IFACE2. + // Of 1045 bytes sent over Cell, expect 700 bytes attributed to UID_RED, 250 bytes + // attributed to UID_BLUE, and 95 bytes attributed to UID_VPN. + // Of 3850 bytes received over Cell, expect 3000 bytes attributed to UID_RED, 500 bytes + // attributed to UID_BLUE, and 350 bytes attributed to UID_VPN. + final NetworkStats tunStats = + parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_two_vpn); + + assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L); + assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L); + assertValues(tunStats, TEST_IFACE2, UID_RED, 3000L, 300L, 700L, 70L); + assertValues(tunStats, TEST_IFACE2, UID_BLUE, 500L, 50L, 250L, 25L); + assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 150L, 0L); + assertValues(tunStats, TEST_IFACE2, UID_VPN, 350L, 0L, 95L, 0L); + } + + @Test + public void testVpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception { // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set. // Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell. @@ -291,7 +331,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception { + public void testVpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception { // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set. // Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell. @@ -314,7 +354,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { } @Test - public void vpnWithIncorrectUnderlyingIface() throws Exception { + public void testVpnWithIncorrectUnderlyingIface() throws Exception { // WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2), // but has declared only WiFi (TEST_IFACE) in its underlying network set. VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn new file mode 100644 index 000000000000..eb0513b10049 --- /dev/null +++ b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn @@ -0,0 +1,9 @@ +idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets +2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 +3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0 +4 test_nss_tun1 0x0 1001 0 3000 300 700 70 0 0 0 0 0 0 0 0 0 0 0 0 +5 test_nss_tun1 0x0 1002 0 500 50 250 25 0 0 0 0 0 0 0 0 0 0 0 0 +6 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +7 test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0 +8 test1 0x0 1004 0 3850 350 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +9 test1 0x0 1004 1 0 0 1045 95 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h index e7be43459e16..852b1244cd6e 100644 --- a/tools/aapt2/cmd/Link.h +++ b/tools/aapt2/cmd/Link.h @@ -263,6 +263,10 @@ class LinkCommand : public Command { "Changes the name of the target package for instrumentation. Most useful\n" "when used in conjunction with --rename-manifest-package.", &options_.manifest_fixer_options.rename_instrumentation_target_package); + AddOptionalFlag("--rename-overlay-target-package", + "Changes the name of the target package for overlay. Most useful\n" + "when used in conjunction with --rename-manifest-package.", + &options_.manifest_fixer_options.rename_overlay_target_package); AddOptionalFlagList("-0", "File suffix not to compress.", &options_.extensions_to_not_compress); AddOptionalSwitch("--no-compress", "Do not compress any resources.", diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index bcfce663db00..c813a446b8db 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -263,6 +263,16 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, } } + if (options_.rename_overlay_target_package) { + if (!util::IsJavaPackageName(options_.rename_overlay_target_package.value())) { + diag->Error(DiagMessage() + << "invalid overlay target package override '" + << options_.rename_overlay_target_package.value() + << "'"); + return false; + } + } + // Common <intent-filter> actions. xml::XmlNodeAction intent_filter_action; intent_filter_action["action"].Action(RequiredNameIsNotEmpty); @@ -373,7 +383,17 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, manifest_action["attribution"]; manifest_action["attribution"]["inherit-from"]; manifest_action["original-package"]; - manifest_action["overlay"]; + manifest_action["overlay"].Action([&](xml::Element* el) -> bool { + if (!options_.rename_overlay_target_package) { + return true; + } + + if (xml::Attribute* attr = + el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) { + attr->value = options_.rename_overlay_target_package.value(); + } + return true; + }); manifest_action["protected-broadcast"]; manifest_action["adopt-permissions"]; manifest_action["uses-permission"]; diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h index 3ef57d0d0e42..ec4367b450fb 100644 --- a/tools/aapt2/link/ManifestFixer.h +++ b/tools/aapt2/link/ManifestFixer.h @@ -44,6 +44,10 @@ struct ManifestFixerOptions { // <instrumentation>. Maybe<std::string> rename_instrumentation_target_package; + // The Android package to use instead of the one defined in 'android:targetPackage' in + // <overlay>. + Maybe<std::string> rename_overlay_target_package; + // The version name to set if 'android:versionName' is not defined in <manifest> or if // replace_version is set. Maybe<std::string> version_name_default; diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp index 3af06f53d4f3..0791805e2506 100644 --- a/tools/aapt2/link/ManifestFixer_test.cpp +++ b/tools/aapt2/link/ManifestFixer_test.cpp @@ -325,6 +325,32 @@ TEST_F(ManifestFixerTest, EXPECT_THAT(attr->value, StrEq("com.android")); } +TEST_F(ManifestFixerTest, + RenameManifestOverlayPackageAndFullyQualifyTarget) { + ManifestFixerOptions options; + options.rename_overlay_target_package = std::string("com.android"); + + std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( + <manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android"> + <overlay android:targetName="Customization" android:targetPackage="android" /> + </manifest>)EOF", + options); + ASSERT_THAT(doc, NotNull()); + + xml::Element* manifest_el = doc->root.get(); + ASSERT_THAT(manifest_el, NotNull()); + + xml::Element* overlay_el = + manifest_el->FindChild({}, "overlay"); + ASSERT_THAT(overlay_el, NotNull()); + + xml::Attribute* attr = + overlay_el->FindAttribute(xml::kSchemaAndroid, "targetPackage"); + ASSERT_THAT(attr, NotNull()); + EXPECT_THAT(attr->value, StrEq("com.android")); +} + TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) { ManifestFixerOptions options; options.version_name_default = std::string("Beta"); |