diff options
749 files changed, 20695 insertions, 8293 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING index e178583bca78..a48ce0ce1b6c 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -15,6 +15,22 @@ ] } ], + "presubmit-pm": [ + { + "name": "PackageManagerServiceServerTests", + "options": [ + { + "include-annotation": "android.platform.test.annotations.Presubmit" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation": "org.junit.Ignore" + } + ] + } + ], "presubmit": [ { "name": "ManagedProvisioningTests", @@ -167,6 +183,20 @@ "exclude-annotation": "org.junit.Ignore" } ] + }, + { + "name": "PackageManagerServiceServerTests", + "options": [ + { + "include-annotation": "android.platform.test.annotations.Presubmit" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation": "org.junit.Ignore" + } + ] } ] } diff --git a/apex/jobscheduler/framework/java/android/app/job/JobService.java b/apex/jobscheduler/framework/java/android/app/job/JobService.java index dabf7282a9e0..bad641cf8bf6 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobService.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobService.java @@ -210,6 +210,7 @@ public abstract class JobService extends Service { * 30 seconds for a data transfer job if a payload size estimate * was not provided at the time of scheduling. * + * @hide * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) */ public final void updateEstimatedNetworkBytes(@NonNull JobParameters params, @@ -227,6 +228,7 @@ public abstract class JobService extends Service { * 30 seconds for a data transfer job if a payload size estimate * was not provided at the time of scheduling. * + * @hide * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) */ public final void updateEstimatedNetworkBytes(@NonNull JobParameters params, @@ -237,6 +239,7 @@ public abstract class JobService extends Service { /** * Tell JobScheduler how much data has successfully been transferred for the data transfer job. + * @hide */ public final void updateTransferredNetworkBytes(@NonNull JobParameters params, @BytesLong long transferredDownloadBytes, @BytesLong long transferredUploadBytes) { @@ -247,6 +250,7 @@ public abstract class JobService extends Service { /** * Tell JobScheduler how much data has been transferred for the data transfer * {@link JobWorkItem}. + * @hide */ public final void updateTransferredNetworkBytes(@NonNull JobParameters params, @NonNull JobWorkItem item, @@ -264,6 +268,7 @@ public abstract class JobService extends Service { * <p> * This must be implemented for all data transfer jobs. * + * @hide * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) * @see JobInfo#NETWORK_BYTES_UNKNOWN */ @@ -287,6 +292,7 @@ public abstract class JobService extends Service { * <p> * This must be implemented for all data transfer jobs. * + * @hide * @see JobInfo.Builder#setEstimatedNetworkBytes(long, long) * @see JobInfo#NETWORK_BYTES_UNKNOWN */ @@ -313,6 +319,7 @@ public abstract class JobService extends Service { * <p> * This must be implemented for all data transfer jobs. * + * @hide * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting @@ -341,6 +348,7 @@ public abstract class JobService extends Service { * <p> * This must be implemented for all data transfer jobs. * + * @hide * @see JobInfo#NETWORK_BYTES_UNKNOWN */ // TODO(255371817): specify the actual time JS will wait for progress before requesting diff --git a/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java b/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java index 6c4b6863ae9e..83296a63205a 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java @@ -367,6 +367,7 @@ public abstract class JobServiceEngine { /** * Engine's request to get how much data has been downloaded. * + * @hide * @see JobService#getTransferredDownloadBytes() */ @BytesLong @@ -381,6 +382,7 @@ public abstract class JobServiceEngine { /** * Engine's request to get how much data has been uploaded. * + * @hide * @see JobService#getTransferredUploadBytes() */ @BytesLong @@ -395,6 +397,7 @@ public abstract class JobServiceEngine { /** * Call in to engine to report data transfer progress. * + * @hide * @see JobService#updateTransferredNetworkBytes(JobParameters, long, long) */ public void updateTransferredNetworkBytes(@NonNull JobParameters params, @@ -413,6 +416,7 @@ public abstract class JobServiceEngine { /** * Call in to engine to report data transfer progress. * + * @hide * @see JobService#updateEstimatedNetworkBytes(JobParameters, JobWorkItem, long, long) */ public void updateEstimatedNetworkBytes(@NonNull JobParameters params, diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java index c2602f246ce4..145ac52ccc8a 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java @@ -412,6 +412,14 @@ public final class JobStore { /** Version of the db schema. */ private static final int JOBS_FILE_VERSION = 1; + /** + * For legacy reasons, this tag is used to encapsulate the entire job list. + */ + private static final String XML_TAG_JOB_INFO = "job-info"; + /** + * For legacy reasons, this tag represents a single {@link JobStatus} object. + */ + private static final String XML_TAG_JOB = "job"; /** Tag corresponds to constraints this job needs. */ private static final String XML_TAG_PARAMS_CONSTRAINTS = "constraints"; /** Tag corresponds to execution parameters. */ @@ -645,19 +653,19 @@ public final class JobStore { out.startDocument(null, true); out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - out.startTag(null, "job-info"); + out.startTag(null, XML_TAG_JOB_INFO); out.attribute(null, "version", Integer.toString(JOBS_FILE_VERSION)); for (int i=0; i<jobList.size(); i++) { JobStatus jobStatus = jobList.get(i); if (DEBUG) { Slog.d(TAG, "Saving job " + jobStatus.getJobId()); } - out.startTag(null, "job"); + out.startTag(null, XML_TAG_JOB); addAttributesToJobTag(out, jobStatus); writeConstraintsToXml(out, jobStatus); writeExecutionCriteriaToXml(out, jobStatus); writeBundleToXml(jobStatus.getJob().getExtras(), out); - out.endTag(null, "job"); + out.endTag(null, XML_TAG_JOB); numJobs++; if (jobStatus.getUid() == Process.SYSTEM_UID) { @@ -667,7 +675,7 @@ public final class JobStore { } } } - out.endTag(null, "job-info"); + out.endTag(null, XML_TAG_JOB_INFO); out.endDocument(); file.finishWrite(fos); @@ -903,17 +911,17 @@ public final class JobStore { return; } boolean needFileMigration = false; - long now = sElapsedRealtimeClock.millis(); + long nowElapsed = sElapsedRealtimeClock.millis(); for (File file : files) { final AtomicFile aFile = createJobFile(file); try (FileInputStream fis = aFile.openRead()) { synchronized (mLock) { - jobs = readJobMapImpl(fis, rtcGood); + jobs = readJobMapImpl(fis, rtcGood, nowElapsed); if (jobs != null) { for (int i = 0; i < jobs.size(); i++) { JobStatus js = jobs.get(i); js.prepareLocked(); - js.enqueueTime = now; + js.enqueueTime = nowElapsed; this.jobSet.add(js); numJobs++; @@ -959,7 +967,7 @@ public final class JobStore { } } - private List<JobStatus> readJobMapImpl(InputStream fis, boolean rtcIsGood) + private List<JobStatus> readJobMapImpl(InputStream fis, boolean rtcIsGood, long nowElapsed) throws XmlPullParserException, IOException { TypedXmlPullParser parser = Xml.resolvePullParser(fis); @@ -977,28 +985,24 @@ public final class JobStore { } String tagName = parser.getName(); - if ("job-info".equals(tagName)) { + if (XML_TAG_JOB_INFO.equals(tagName)) { final List<JobStatus> jobs = new ArrayList<JobStatus>(); - final int version; + final int version = parser.getAttributeInt(null, "version"); // Read in version info. - try { - version = Integer.parseInt(parser.getAttributeValue(null, "version")); - if (version > JOBS_FILE_VERSION || version < 0) { - Slog.d(TAG, "Invalid version number, aborting jobs file read."); - return null; - } - } catch (NumberFormatException e) { - Slog.e(TAG, "Invalid version number, aborting jobs file read."); + if (version > JOBS_FILE_VERSION || version < 0) { + Slog.d(TAG, "Invalid version number, aborting jobs file read."); return null; } + eventType = parser.next(); do { // Read each <job/> if (eventType == XmlPullParser.START_TAG) { tagName = parser.getName(); // Start reading job. - if ("job".equals(tagName)) { - JobStatus persistedJob = restoreJobFromXml(rtcIsGood, parser, version); + if (XML_TAG_JOB.equals(tagName)) { + JobStatus persistedJob = + restoreJobFromXml(rtcIsGood, parser, version, nowElapsed); if (persistedJob != null) { if (DEBUG) { Slog.d(TAG, "Read out " + persistedJob); @@ -1022,7 +1026,7 @@ public final class JobStore { * @return Newly instantiated job holding all the information we just read out of the xml tag. */ private JobStatus restoreJobFromXml(boolean rtcIsGood, TypedXmlPullParser parser, - int schemaVersion) throws XmlPullParserException, IOException { + int schemaVersion, long nowElapsed) throws XmlPullParserException, IOException { JobInfo.Builder jobBuilder; int uid, sourceUserId; long lastSuccessfulRunTime; @@ -1113,18 +1117,9 @@ public final class JobStore { } // Tuple of (earliest runtime, latest runtime) in UTC. - final Pair<Long, Long> rtcRuntimes; - try { - rtcRuntimes = buildRtcExecutionTimesFromXml(parser); - } catch (NumberFormatException e) { - if (DEBUG) { - Slog.d(TAG, "Error parsing execution time parameters, skipping."); - } - return null; - } + final Pair<Long, Long> rtcRuntimes = buildRtcExecutionTimesFromXml(parser); - final long elapsedNow = sElapsedRealtimeClock.millis(); - Pair<Long, Long> elapsedRuntimes = convertRtcBoundsToElapsed(rtcRuntimes, elapsedNow); + Pair<Long, Long> elapsedRuntimes = convertRtcBoundsToElapsed(rtcRuntimes, nowElapsed); if (XML_TAG_PERIODIC.equals(parser.getName())) { try { @@ -1137,8 +1132,8 @@ public final class JobStore { // from now. This is the latest the periodic could be pushed out. This could // happen if the periodic ran early (at flex time before period), and then the // device rebooted. - if (elapsedRuntimes.second > elapsedNow + periodMillis + flexMillis) { - final long clampedLateRuntimeElapsed = elapsedNow + flexMillis + if (elapsedRuntimes.second > nowElapsed + periodMillis + flexMillis) { + final long clampedLateRuntimeElapsed = nowElapsed + flexMillis + periodMillis; final long clampedEarlyRuntimeElapsed = clampedLateRuntimeElapsed - flexMillis; @@ -1163,11 +1158,11 @@ public final class JobStore { } else if (XML_TAG_ONEOFF.equals(parser.getName())) { try { if (elapsedRuntimes.first != JobStatus.NO_EARLIEST_RUNTIME) { - jobBuilder.setMinimumLatency(elapsedRuntimes.first - elapsedNow); + jobBuilder.setMinimumLatency(elapsedRuntimes.first - nowElapsed); } if (elapsedRuntimes.second != JobStatus.NO_LATEST_RUNTIME) { jobBuilder.setOverrideDeadline( - elapsedRuntimes.second - elapsedNow); + elapsedRuntimes.second - nowElapsed); } } catch (NumberFormatException e) { Slog.d(TAG, "Error reading job execution criteria, skipping."); @@ -1236,7 +1231,7 @@ public final class JobStore { // And now we're done final int appBucket = JobSchedulerService.standbyBucketForPackage(sourcePackageName, - sourceUserId, elapsedNow); + sourceUserId, nowElapsed); JobStatus js = new JobStatus( builtJob, uid, sourcePackageName, sourceUserId, appBucket, sourceTag, @@ -1246,9 +1241,10 @@ public final class JobStore { return js; } - private JobInfo.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException { + private JobInfo.Builder buildBuilderFromXml(TypedXmlPullParser parser) + throws XmlPullParserException { // Pull out required fields from <job> attributes. - int jobId = Integer.parseInt(parser.getAttributeValue(null, "jobid")); + int jobId = parser.getAttributeInt(null, "jobid"); String packageName = parser.getAttributeValue(null, "package"); String className = parser.getAttributeValue(null, "class"); ComponentName cname = new ComponentName(packageName, className); @@ -1405,20 +1401,13 @@ public final class JobStore { * @return A Pair of timestamps in UTC wall-clock time. The first is the earliest * time at which the job is to become runnable, and the second is the deadline at * which it becomes overdue to execute. - * @throws NumberFormatException */ - private Pair<Long, Long> buildRtcExecutionTimesFromXml(XmlPullParser parser) - throws NumberFormatException { - String val; + private Pair<Long, Long> buildRtcExecutionTimesFromXml(TypedXmlPullParser parser) { // Pull out execution time data. - val = parser.getAttributeValue(null, "delay"); - final long earliestRunTimeRtc = (val != null) - ? Long.parseLong(val) - : JobStatus.NO_EARLIEST_RUNTIME; - val = parser.getAttributeValue(null, "deadline"); - final long latestRunTimeRtc = (val != null) - ? Long.parseLong(val) - : JobStatus.NO_LATEST_RUNTIME; + final long earliestRunTimeRtc = + parser.getAttributeLong(null, "delay", JobStatus.NO_EARLIEST_RUNTIME); + final long latestRunTimeRtc = + parser.getAttributeLong(null, "deadline", JobStatus.NO_LATEST_RUNTIME); return Pair.create(earliestRunTimeRtc, latestRunTimeRtc); } } 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 67d711c79b15..b1c8b511ac25 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -63,6 +63,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.AppOpsManager; import android.app.usage.AppStandbyInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager.ForcedReasons; @@ -108,6 +109,7 @@ import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.util.SparseIntArray; import android.util.SparseLongArray; import android.util.TimeUtils; import android.view.Display; @@ -116,6 +118,8 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.IAppOpsCallback; +import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.internal.util.ArrayUtils; import com.android.internal.util.ConcurrentUtils; @@ -279,6 +283,13 @@ public class AppStandbyController @GuardedBy("mPendingIdleStateChecks") private final SparseLongArray mPendingIdleStateChecks = new SparseLongArray(); + /** + * Map of uids to their current app-op mode for + * {@link AppOpsManager#OPSTR_SYSTEM_EXEMPT_FROM_APP_STANDBY}. + */ + @GuardedBy("mSystemExemptionAppOpMode") + private final SparseIntArray mSystemExemptionAppOpMode = new SparseIntArray(); + // Cache the active network scorer queried from the network scorer service private volatile String mCachedNetworkScorer = null; // The last time the network scorer service was queried @@ -488,6 +499,7 @@ public class AppStandbyController private AppWidgetManager mAppWidgetManager; private PackageManager mPackageManager; + private AppOpsManager mAppOpsManager; Injector mInjector; private static class Pool<T> { @@ -647,6 +659,28 @@ public class AppStandbyController settingsObserver.start(); mAppWidgetManager = mContext.getSystemService(AppWidgetManager.class); + mAppOpsManager = mContext.getSystemService(AppOpsManager.class); + IAppOpsService iAppOpsService = mInjector.getAppOpsService(); + try { + iAppOpsService.startWatchingMode( + AppOpsManager.OP_SYSTEM_EXEMPT_FROM_APP_STANDBY, + /*packageName=*/ null, + new IAppOpsCallback.Stub() { + @Override + public void opChanged(int op, int uid, String packageName) { + final int userId = UserHandle.getUserId(uid); + synchronized (mSystemExemptionAppOpMode) { + mSystemExemptionAppOpMode.delete(uid); + } + mHandler.obtainMessage( + MSG_CHECK_PACKAGE_IDLE_STATE, userId, uid, packageName) + .sendToTarget(); + } + }); + } catch (RemoteException e) { + // Should not happen. + Slog.wtf(TAG, "Failed start watching for app op", e); + } mInjector.registerDisplayListener(mDisplayListener, mHandler); synchronized (mAppIdleLock) { @@ -1417,6 +1451,23 @@ public class AppStandbyController return STANDBY_BUCKET_EXEMPTED; } + final int uid = UserHandle.getUid(userId, appId); + synchronized (mSystemExemptionAppOpMode) { + if (mSystemExemptionAppOpMode.indexOfKey(uid) >= 0) { + if (mSystemExemptionAppOpMode.get(uid) + == AppOpsManager.MODE_ALLOWED) { + return STANDBY_BUCKET_EXEMPTED; + } + } else { + int mode = mAppOpsManager.checkOpNoThrow( + AppOpsManager.OP_SYSTEM_EXEMPT_FROM_APP_STANDBY, uid, packageName); + mSystemExemptionAppOpMode.put(uid, mode); + if (mode == AppOpsManager.MODE_ALLOWED) { + return STANDBY_BUCKET_EXEMPTED; + } + } + } + if (mAppWidgetManager != null && mInjector.isBoundWidgetPackage(mAppWidgetManager, packageName, userId)) { return STANDBY_BUCKET_ACTIVE; @@ -2129,6 +2180,12 @@ public class AppStandbyController clearAppIdleForPackage(pkgName, userId); } } + synchronized (mSystemExemptionAppOpMode) { + if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { + mSystemExemptionAppOpMode.delete(UserHandle.getUid(userId, getAppId(pkgName))); + } + } + } } @@ -2524,6 +2581,11 @@ public class AppStandbyController } } + IAppOpsService getAppOpsService() { + return IAppOpsService.Stub.asInterface( + ServiceManager.getService(Context.APP_OPS_SERVICE)); + } + /** * Returns {@code true} if the supplied package is the wellbeing app. Otherwise, * returns {@code false}. diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index 7a08cbdcddd4..5f06c971ba98 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -71,6 +71,7 @@ cc_library { host_supported: true, srcs: [ "libidmap2/**/*.cpp", + "self_targeting/*.cpp", ], export_include_dirs: ["include"], target: { diff --git a/cmds/idmap2/include/idmap2/ResourceContainer.h b/cmds/idmap2/include/idmap2/ResourceContainer.h index 2452ff0784ce..4d2832113f71 100644 --- a/cmds/idmap2/include/idmap2/ResourceContainer.h +++ b/cmds/idmap2/include/idmap2/ResourceContainer.h @@ -46,14 +46,6 @@ struct TargetResourceContainer : public ResourceContainer { ~TargetResourceContainer() override = default; }; -struct OverlayManifestInfo { - std::string package_name; // NOLINT(misc-non-private-member-variables-in-classes) - std::string name; // NOLINT(misc-non-private-member-variables-in-classes) - std::string target_package; // NOLINT(misc-non-private-member-variables-in-classes) - std::string target_name; // NOLINT(misc-non-private-member-variables-in-classes) - ResourceId resource_mapping; // NOLINT(misc-non-private-member-variables-in-classes) -}; - struct OverlayData { struct ResourceIdValue { // The overlay resource id. diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h index 2214a83bd2da..c2b0abed442c 100644 --- a/cmds/idmap2/include/idmap2/ResourceUtils.h +++ b/cmds/idmap2/include/idmap2/ResourceUtils.h @@ -30,13 +30,13 @@ namespace android::idmap2 { #define EXTRACT_ENTRY(resid) (0x0000ffff & (resid)) // use typedefs to let the compiler warn us about implicit casts -using ResourceId = uint32_t; // 0xpptteeee +using ResourceId = android::ResourceId; // 0xpptteeee using PackageId = uint8_t; // pp in 0xpptteeee using TypeId = uint8_t; // tt in 0xpptteeee using EntryId = uint16_t; // eeee in 0xpptteeee -using DataType = uint8_t; // Res_value::dataType -using DataValue = uint32_t; // Res_value::data +using DataType = android::DataType; // Res_value::dataType +using DataValue = android::DataValue; // Res_value::data struct TargetValue { DataType data_type; diff --git a/cmds/idmap2/self_targeting/SelfTargeting.cpp b/cmds/idmap2/self_targeting/SelfTargeting.cpp new file mode 100644 index 000000000000..20aa7d32a3c2 --- /dev/null +++ b/cmds/idmap2/self_targeting/SelfTargeting.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/stat.h> + +#include <fstream> +#include <optional> + +#define LOG_TAG "SelfTargeting" + +#include "androidfw/ResourceTypes.h" +#include "idmap2/BinaryStreamVisitor.h" +#include "idmap2/FabricatedOverlay.h" +#include "idmap2/Idmap.h" +#include "idmap2/Result.h" + +using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; +using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; +using android::idmap2::BinaryStreamVisitor; +using android::idmap2::Idmap; +using android::idmap2::OverlayResourceContainer; + +namespace android::self_targeting { + +constexpr const mode_t kIdmapFilePermission = S_IRUSR | S_IWUSR; // u=rw-, g=---, o=--- + +extern "C" bool +CreateFrroFile(std::string& out_err_result, std::string& packageName, std::string& overlayName, + std::string& targetPackageName, std::optional<std::string>& targetOverlayable, + std::vector<FabricatedOverlayEntryParameters>& entries_params, + const std::string& frro_file_path) { + android::idmap2::FabricatedOverlay::Builder builder(packageName, overlayName, + targetPackageName); + if (targetOverlayable.has_value()) { + builder.SetOverlayable(targetOverlayable.value_or(std::string())); + } + for (const auto& entry_params : entries_params) { + const auto dataType = entry_params.data_type; + if (entry_params.data_binary_value.has_value()) { + builder.SetResourceValue(entry_params.resource_name, *entry_params.data_binary_value, + entry_params.configuration); + } else if (dataType >= Res_value::TYPE_FIRST_INT && dataType <= Res_value::TYPE_LAST_INT) { + builder.SetResourceValue(entry_params.resource_name, dataType, + entry_params.data_value, entry_params.configuration); + } else if (dataType == Res_value::TYPE_STRING) { + builder.SetResourceValue(entry_params.resource_name, dataType, + entry_params.data_string_value , entry_params.configuration); + } else { + out_err_result = base::StringPrintf("Unsupported data type %d", dataType); + return false; + } + } + + const auto frro = builder.Build(); + std::ofstream fout(frro_file_path); + if (fout.fail()) { + out_err_result = base::StringPrintf("open output stream fail %s", std::strerror(errno)); + return false; + } + auto result = frro->ToBinaryStream(fout); + if (!result) { + unlink(frro_file_path.c_str()); + out_err_result = base::StringPrintf("to stream fail %s", result.GetErrorMessage().c_str()); + return false; + } + fout.close(); + if (fout.fail()) { + unlink(frro_file_path.c_str()); + out_err_result = base::StringPrintf("output stream fail %s", std::strerror(errno)); + return false; + } + if (chmod(frro_file_path.c_str(), kIdmapFilePermission) == -1) { + out_err_result = base::StringPrintf("Failed to change the file permission %s", + frro_file_path.c_str()); + return false; + } + return true; +} + +extern "C" bool +CreateIdmapFile(std::string& out_err, const std::string& targetPath, const std::string& overlayPath, + const std::string& idmapPath, const std::string& overlayName) { + // idmap files are mapped with mmap in libandroidfw. Deleting and recreating the idmap + // guarantees that existing memory maps will continue to be valid and unaffected. The file must + // be deleted before attempting to create the idmap, so that if idmap creation fails, the + // overlay will no longer be usable. + unlink(idmapPath.c_str()); + + const auto target = idmap2::TargetResourceContainer::FromPath(targetPath); + if (!target) { + out_err = base::StringPrintf("Failed to load target %s because of %s", targetPath.c_str(), + target.GetErrorMessage().c_str()); + return false; + } + + const auto overlay = OverlayResourceContainer::FromPath(overlayPath); + if (!overlay) { + out_err = base::StringPrintf("Failed to load overlay %s because of %s", overlayPath.c_str(), + overlay.GetErrorMessage().c_str()); + return false; + } + + // Overlay self target process. Only allow self-targeting types. + const auto fulfilled_policies = static_cast<PolicyBitmask>( + PolicyFlags::PUBLIC | PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION | + PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE | PolicyFlags::ODM_PARTITION | + PolicyFlags::OEM_PARTITION | PolicyFlags::ACTOR_SIGNATURE | + PolicyFlags::CONFIG_SIGNATURE); + + const auto idmap = Idmap::FromContainers(**target, **overlay, overlayName, + fulfilled_policies, false /* enforce_overlayable */); + if (!idmap) { + out_err = base::StringPrintf("Failed to create idmap because of %s", + idmap.GetErrorMessage().c_str()); + return false; + } + + std::ofstream fout(idmapPath.c_str()); + if (fout.fail()) { + out_err = base::StringPrintf("Failed to create idmap %s because of %s", idmapPath.c_str(), + strerror(errno)); + return false; + } + + BinaryStreamVisitor visitor(fout); + (*idmap)->accept(&visitor); + fout.close(); + if (fout.fail()) { + unlink(idmapPath.c_str()); + out_err = base::StringPrintf("Failed to write idmap %s because of %s", idmapPath.c_str(), + strerror(errno)); + return false; + } + if (chmod(idmapPath.c_str(), kIdmapFilePermission) == -1) { + out_err = base::StringPrintf("Failed to change the file permission %s", idmapPath.c_str()); + return false; + } + return true; +} + +extern "C" bool +GetFabricatedOverlayInfo(std::string& out_err, const std::string& overlay_path, + OverlayManifestInfo& out_info) { + const auto overlay = idmap2::FabricatedOverlayContainer::FromPath(overlay_path); + if (!overlay) { + out_err = base::StringPrintf("Failed to write idmap %s because of %s", + overlay_path.c_str(), strerror(errno)); + return false; + } + + out_info = (*overlay)->GetManifestInfo(); + + return true; +} + +} // namespace android::self_targeting + diff --git a/core/api/current.txt b/core/api/current.txt index de8a10d467c1..d4c461cd9384 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -5291,11 +5291,8 @@ package android.app { field @NonNull public static final android.os.Parcelable.Creator<android.app.ForegroundServiceStartNotAllowedException> CREATOR; } - public final class ForegroundServiceTypeNotAllowedException extends android.app.ServiceStartNotAllowedException implements android.os.Parcelable { - ctor public ForegroundServiceTypeNotAllowedException(@NonNull String); - method public int describeContents(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.app.ForegroundServiceTypeNotAllowedException> CREATOR; + public abstract class ForegroundServiceTypeException extends android.app.ServiceStartNotAllowedException { + ctor public ForegroundServiceTypeException(@NonNull String); } @Deprecated public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener { @@ -5738,6 +5735,13 @@ package android.app { method @Deprecated public void setIntentRedelivery(boolean); } + public final class InvalidForegroundServiceTypeException extends android.app.ForegroundServiceTypeException implements android.os.Parcelable { + ctor public InvalidForegroundServiceTypeException(@NonNull String); + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.InvalidForegroundServiceTypeException> CREATOR; + } + public class KeyguardManager { method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addKeyguardLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.KeyguardLockedStateListener); method @Deprecated public android.content.Intent createConfirmDeviceCredentialIntent(CharSequence, CharSequence); @@ -5892,6 +5896,13 @@ package android.app { method public void showDialog(); } + public final class MissingForegroundServiceTypeException extends android.app.ForegroundServiceTypeException implements android.os.Parcelable { + ctor public MissingForegroundServiceTypeException(@NonNull String); + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.MissingForegroundServiceTypeException> CREATOR; + } + public class NativeActivity extends android.app.Activity implements android.view.InputQueue.Callback android.view.SurfaceHolder.Callback2 android.view.ViewTreeObserver.OnGlobalLayoutListener { ctor public NativeActivity(); method public void onGlobalLayout(); @@ -8475,31 +8486,19 @@ package android.app.job { public abstract class JobService extends android.app.Service { ctor public JobService(); - method public long getTransferredDownloadBytes(); - method public long getTransferredDownloadBytes(@NonNull android.app.job.JobWorkItem); - method public long getTransferredUploadBytes(); - method public long getTransferredUploadBytes(@NonNull android.app.job.JobWorkItem); method public final void jobFinished(android.app.job.JobParameters, boolean); method public final android.os.IBinder onBind(android.content.Intent); method public abstract boolean onStartJob(android.app.job.JobParameters); method public abstract boolean onStopJob(android.app.job.JobParameters); - method public final void updateEstimatedNetworkBytes(@NonNull android.app.job.JobParameters, long, long); - method public final void updateEstimatedNetworkBytes(@NonNull android.app.job.JobParameters, @NonNull android.app.job.JobWorkItem, long, long); - method public final void updateTransferredNetworkBytes(@NonNull android.app.job.JobParameters, long, long); - method public final void updateTransferredNetworkBytes(@NonNull android.app.job.JobParameters, @NonNull android.app.job.JobWorkItem, long, long); field public static final String PERMISSION_BIND = "android.permission.BIND_JOB_SERVICE"; } public abstract class JobServiceEngine { ctor public JobServiceEngine(android.app.Service); method public final android.os.IBinder getBinder(); - method public long getTransferredDownloadBytes(@NonNull android.app.job.JobParameters, @Nullable android.app.job.JobWorkItem); - method public long getTransferredUploadBytes(@NonNull android.app.job.JobParameters, @Nullable android.app.job.JobWorkItem); method public void jobFinished(android.app.job.JobParameters, boolean); method public abstract boolean onStartJob(android.app.job.JobParameters); method public abstract boolean onStopJob(android.app.job.JobParameters); - method public void updateEstimatedNetworkBytes(@NonNull android.app.job.JobParameters, @NonNull android.app.job.JobWorkItem, long, long); - method public void updateTransferredNetworkBytes(@NonNull android.app.job.JobParameters, @Nullable android.app.job.JobWorkItem, long, long); } public final class JobWorkItem implements android.os.Parcelable { @@ -12983,6 +12982,14 @@ package android.content.res.loader { package android.credentials { + public final class ClearCredentialStateRequest implements android.os.Parcelable { + ctor public ClearCredentialStateRequest(@NonNull android.os.Bundle); + method public int describeContents(); + method @NonNull public android.os.Bundle getData(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.credentials.ClearCredentialStateRequest> CREATOR; + } + public final class CreateCredentialRequest implements android.os.Parcelable { ctor public CreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle); method public int describeContents(); @@ -13010,6 +13017,7 @@ package android.credentials { } public final class CredentialManager { + method public void clearCredentialState(@NonNull android.credentials.ClearCredentialStateRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.CredentialManagerException>); method public void executeCreateCredential(@NonNull android.credentials.CreateCredentialRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.CreateCredentialResponse,android.credentials.CredentialManagerException>); method public void executeGetCredential(@NonNull android.credentials.GetCredentialRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.CredentialManagerException>); } @@ -20899,8 +20907,11 @@ package android.media { method public void onRoutingChanged(android.media.AudioRouting); } - public final class AudioTimestamp { + public final class AudioTimestamp implements android.os.Parcelable { ctor public AudioTimestamp(); + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioTimestamp> CREATOR; field public static final int TIMEBASE_BOOTTIME = 1; // 0x1 field public static final int TIMEBASE_MONOTONIC = 0; // 0x0 field public long framePosition; @@ -23521,6 +23532,7 @@ package android.media { method public void registerRouteCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.RouteCallback, @NonNull android.media.RouteDiscoveryPreference); method public void registerTransferCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.TransferCallback); method public void setOnGetControllerHintsListener(@Nullable android.media.MediaRouter2.OnGetControllerHintsListener); + method public void setRouteListingPreference(@Nullable android.media.RouteListingPreference); method public void stop(); method public void transferTo(@NonNull android.media.MediaRoute2Info); method public void unregisterControllerCallback(@NonNull android.media.MediaRouter2.ControllerCallback); @@ -23894,6 +23906,22 @@ package android.media { method @NonNull public android.media.RouteDiscoveryPreference.Builder setShouldPerformActiveScan(boolean); } + public final class RouteListingPreference implements android.os.Parcelable { + ctor public RouteListingPreference(@NonNull java.util.List<android.media.RouteListingPreference.Item>); + method public int describeContents(); + method @NonNull public java.util.List<android.media.RouteListingPreference.Item> getItems(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference> CREATOR; + } + + public static final class RouteListingPreference.Item implements android.os.Parcelable { + ctor public RouteListingPreference.Item(@NonNull String); + method public int describeContents(); + method @NonNull public String getRouteId(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference.Item> CREATOR; + } + public final class RoutingSessionInfo implements android.os.Parcelable { method public int describeContents(); method @NonNull public String getClientPackageName(); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 2b8d751f616a..eac990d671cd 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -2958,6 +2958,7 @@ package android.companion.virtual { method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close(); method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.audio.VirtualAudioDevice createVirtualAudioDevice(@NonNull android.hardware.display.VirtualDisplay, @Nullable java.util.concurrent.Executor, @Nullable android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChangeCallback); method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @Nullable android.view.Surface, int, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.display.VirtualDisplay.Callback); + method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @NonNull java.util.List<java.lang.String>, @Nullable android.view.Surface, int, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.display.VirtualDisplay.Callback); method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualDpad createVirtualDpad(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); @@ -3112,6 +3113,7 @@ package android.content { field public static final String APP_HIBERNATION_SERVICE = "app_hibernation"; field public static final String APP_INTEGRITY_SERVICE = "app_integrity"; field public static final String APP_PREDICTION_SERVICE = "app_prediction"; + field public static final String AUDIO_DEVICE_VOLUME_SERVICE = "audio_device_volume"; field public static final String BACKUP_SERVICE = "backup"; field public static final String BATTERY_STATS_SERVICE = "batterystats"; field public static final int BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS = 1048576; // 0x100000 @@ -3145,6 +3147,7 @@ package android.content { field public static final String TRANSLATION_MANAGER_SERVICE = "translation"; field public static final String UI_TRANSLATION_SERVICE = "ui_translation"; field public static final String UWB_SERVICE = "uwb"; + field public static final String VIRTUALIZATION_SERVICE = "virtualization"; field public static final String VR_SERVICE = "vrmanager"; field public static final String WALLPAPER_EFFECTS_GENERATION_SERVICE = "wallpaper_effects_generation"; field public static final String WEARABLE_SENSING_SERVICE = "wearable_sensing"; @@ -4159,15 +4162,18 @@ package android.hardware.hdmi { method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public java.util.List<java.lang.String> getAllowedCecSettingStringValues(@NonNull String); method @Nullable public android.hardware.hdmi.HdmiClient getClient(int); method @NonNull public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevices(); + method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getEarcEnabled(); method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecEnabled(); method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecVersion(); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecVolumeControlEnabled(); method public int getPhysicalAddress(); method @Nullable public android.hardware.hdmi.HdmiPlaybackClient getPlaybackClient(); + method @NonNull public java.util.List<android.hardware.hdmi.HdmiPortInfo> getPortInfo(); method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerControlMode(); method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerStateChangeOnActiveSourceLost(); method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getRoutingControl(); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSadPresenceInQuery(@NonNull String); + method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSoundbarMode(); method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient(); method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioControl(); method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioModeMuting(); @@ -4180,6 +4186,7 @@ package android.hardware.hdmi { method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void removeHdmiCecEnabledChangeListener(@NonNull android.hardware.hdmi.HdmiControlManager.CecSettingChangeListener); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void removeHotplugEventListener(android.hardware.hdmi.HdmiControlManager.HotplugEventListener); method public void setActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo); + method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setEarcEnabled(@NonNull int); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecEnabled(@NonNull int); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecVersion(@NonNull int); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecVolumeControlEnabled(int); @@ -4188,6 +4195,7 @@ package android.hardware.hdmi { method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setRoutingControl(@NonNull int); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSadPresenceInQuery(@NonNull String, int); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSadsPresenceInQuery(@NonNull java.util.List<java.lang.String>, int); + method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSoundbarMode(int); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setStandbyMode(boolean); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioControl(@NonNull int); method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioModeMuting(@NonNull int); @@ -4215,6 +4223,7 @@ package android.hardware.hdmi { field public static final String CEC_SETTING_NAME_QUERY_SAD_TRUEHD = "query_sad_truehd"; field public static final String CEC_SETTING_NAME_QUERY_SAD_WMAPRO = "query_sad_wmapro"; field public static final String CEC_SETTING_NAME_ROUTING_CONTROL = "routing_control"; + field public static final String CEC_SETTING_NAME_SOUNDBAR_MODE = "soundbar_mode"; field public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL = "system_audio_control"; field public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING = "system_audio_mode_muting"; field public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP = "tv_send_standby_on_sleep"; @@ -4234,6 +4243,8 @@ package android.hardware.hdmi { field public static final int DEVICE_EVENT_ADD_DEVICE = 1; // 0x1 field public static final int DEVICE_EVENT_REMOVE_DEVICE = 2; // 0x2 field public static final int DEVICE_EVENT_UPDATE_DEVICE = 3; // 0x3 + field public static final int EARC_FEATURE_DISABLED = 0; // 0x0 + field public static final int EARC_FEATURE_ENABLED = 1; // 0x1 field public static final String EXTRA_MESSAGE_EXTRA_PARAM1 = "android.hardware.hdmi.extra.MESSAGE_EXTRA_PARAM1"; field public static final String EXTRA_MESSAGE_ID = "android.hardware.hdmi.extra.MESSAGE_ID"; field public static final int HDMI_CEC_CONTROL_DISABLED = 0; // 0x0 @@ -4293,6 +4304,9 @@ package android.hardware.hdmi { field public static final int RESULT_TIMEOUT = 1; // 0x1 field public static final int ROUTING_CONTROL_DISABLED = 0; // 0x0 field public static final int ROUTING_CONTROL_ENABLED = 1; // 0x1 + field public static final String SETTING_NAME_EARC_ENABLED = "earc_enabled"; + field public static final int SOUNDBAR_MODE_DISABLED = 0; // 0x0 + field public static final int SOUNDBAR_MODE_ENABLED = 1; // 0x1 field public static final int SYSTEM_AUDIO_CONTROL_DISABLED = 0; // 0x0 field public static final int SYSTEM_AUDIO_CONTROL_ENABLED = 1; // 0x1 field public static final int SYSTEM_AUDIO_MODE_MUTING_DISABLED = 0; // 0x0 @@ -4467,7 +4481,7 @@ package android.hardware.hdmi { public class HdmiSwitchClient extends android.hardware.hdmi.HdmiClient { method public int getDeviceType(); - method @NonNull public java.util.List<android.hardware.hdmi.HdmiPortInfo> getPortInfo(); + method @Deprecated @NonNull public java.util.List<android.hardware.hdmi.HdmiPortInfo> getPortInfo(); method public void selectPort(int, @NonNull android.hardware.hdmi.HdmiSwitchClient.OnSelectListener); method public void selectPort(int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.hdmi.HdmiSwitchClient.OnSelectListener); } @@ -6311,7 +6325,7 @@ package android.media { } public class AudioDeviceVolumeManager { - ctor public AudioDeviceVolumeManager(@NonNull android.content.Context); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.VolumeInfo getDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes); } @@ -6649,8 +6663,9 @@ package android.media { method public int getMaxVolumeIndex(); method public int getMinVolumeIndex(); method public int getStreamType(); - method @Nullable public android.media.audiopolicy.AudioVolumeGroup getVolumeGroup(); + method @NonNull public android.media.audiopolicy.AudioVolumeGroup getVolumeGroup(); method public int getVolumeIndex(); + method public boolean hasMuteCommand(); method public boolean hasStreamType(); method public boolean hasVolumeGroup(); method public boolean isMuted(); @@ -10554,6 +10569,7 @@ package android.provider { field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot"; field public static final String NAMESPACE_DISPLAY_MANAGER = "display_manager"; field public static final String NAMESPACE_GAME_DRIVER = "game_driver"; + field public static final String NAMESPACE_HDMI_CONTROL = "hdmi_control"; field public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot"; field public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention"; field public static final String NAMESPACE_LMKD_NATIVE = "lmkd_native"; @@ -12802,14 +12818,14 @@ package android.telephony { method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy(); } - public final class CallAttributes implements android.os.Parcelable { - ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality); - method public int describeContents(); - method @NonNull public android.telephony.CallQuality getCallQuality(); - method public int getNetworkType(); - method @NonNull public android.telephony.PreciseCallState getPreciseCallState(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR; + @Deprecated public final class CallAttributes implements android.os.Parcelable { + ctor @Deprecated public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality); + method @Deprecated public int describeContents(); + method @Deprecated @NonNull public android.telephony.CallQuality getCallQuality(); + method @Deprecated public int getNetworkType(); + method @Deprecated @NonNull public android.telephony.PreciseCallState getPreciseCallState(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); + field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR; } public final class CallForwardingInfo implements android.os.Parcelable { @@ -12889,6 +12905,28 @@ package android.telephony { method @NonNull public android.telephony.CallQuality.Builder setUplinkCallQualityLevel(int); } + public final class CallState implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public android.telephony.CallQuality getCallQuality(); + method public int getCallState(); + method public int getImsCallServiceType(); + method @Nullable public String getImsCallSessionId(); + method public int getImsCallType(); + method public int getNetworkType(); + method public void writeToParcel(@Nullable android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallState> CREATOR; + } + + public static final class CallState.Builder { + ctor public CallState.Builder(int); + method @NonNull public android.telephony.CallState build(); + method @NonNull public android.telephony.CallState.Builder setCallQuality(@Nullable android.telephony.CallQuality); + method @NonNull public android.telephony.CallState.Builder setImsCallServiceType(int); + method @NonNull public android.telephony.CallState.Builder setImsCallSessionId(@Nullable String); + method @NonNull public android.telephony.CallState.Builder setImsCallType(int); + method @NonNull public android.telephony.CallState.Builder setNetworkType(int); + } + public class CarrierConfigManager { method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName(); method @NonNull public static android.os.PersistableBundle getDefaultConfig(); @@ -13639,7 +13677,8 @@ package android.telephony { } public static interface TelephonyCallback.CallAttributesListener { - method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes); + method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public default void onCallAttributesChanged(@NonNull android.telephony.CallAttributes); + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public default void onCallStatesChanged(@NonNull java.util.List<android.telephony.CallState>); } public static interface TelephonyCallback.DataEnabledListener { @@ -14740,6 +14779,7 @@ package android.telephony.ims { field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3 field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0 field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1 + field public static final int CALL_TYPE_NONE = 0; // 0x0 field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3 field public static final int CALL_TYPE_VOICE = 2; // 0x2 field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1 diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java index 4cf48abc2ed3..324b8e7a784f 100644 --- a/core/java/android/app/ActivityClient.java +++ b/core/java/android/app/ActivityClient.java @@ -227,12 +227,13 @@ public class ActivityClient { } /** - * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not - * found. + * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if + * the task {@link Configuration} cannot be obtained. */ - public int getTaskWindowingMode(IBinder activityToken) { + @Nullable + public Configuration getTaskConfiguration(IBinder activityToken) { try { - return getActivityClientController().getTaskWindowingMode(activityToken); + return getActivityClientController().getTaskConfiguration(activityToken); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index a61ade08bac6..5aa8f1fda03c 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -47,6 +47,8 @@ import android.app.RemoteServiceException.MissingRequestPasswordComplexityPermis import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; +import android.app.backup.BackupAnnotations.BackupDestination; +import android.app.backup.BackupAnnotations.OperationType; import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ActivityLifecycleItem.LifecycleState; import android.app.servertransaction.ActivityRelaunchItem; @@ -799,7 +801,7 @@ public final class ActivityThread extends ClientTransactionHandler ApplicationInfo appInfo; int backupMode; int userId; - int operationType; + @BackupDestination int backupDestination; public String toString() { return "CreateBackupAgentData{appInfo=" + appInfo + " backupAgent=" + appInfo.backupAgentName @@ -1034,12 +1036,12 @@ public final class ActivityThread extends ClientTransactionHandler } public final void scheduleCreateBackupAgent(ApplicationInfo app, - int backupMode, int userId, int operationType) { + int backupMode, int userId, @BackupDestination int backupDestination) { CreateBackupAgentData d = new CreateBackupAgentData(); d.appInfo = app; d.backupMode = backupMode; d.userId = userId; - d.operationType = operationType; + d.backupDestination = backupDestination; sendMessage(H.CREATE_BACKUP_AGENT, d); } @@ -4402,7 +4404,8 @@ public final class ActivityThread extends ClientTransactionHandler context.setOuterContext(agent); agent.attach(context); - agent.onCreate(UserHandle.of(data.userId), data.operationType); + agent.onCreate(UserHandle.of(data.userId), data.backupDestination, + getOperationTypeFromBackupMode(data.backupMode)); binder = agent.onBind(); backupAgents.put(packageName, agent); } catch (Exception e) { @@ -4430,6 +4433,22 @@ public final class ActivityThread extends ClientTransactionHandler } } + @OperationType + private static int getOperationTypeFromBackupMode(int backupMode) { + switch (backupMode) { + case ApplicationThreadConstants.BACKUP_MODE_RESTORE: + case ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL: + return OperationType.RESTORE; + case ApplicationThreadConstants.BACKUP_MODE_FULL: + case ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL: + return OperationType.BACKUP; + default: + Slog.w(TAG, "Invalid backup mode when initialising BackupAgent: " + + backupMode); + return OperationType.UNKNOWN; + } + } + private String getBackupAgentName(CreateBackupAgentData data) { String agentName = data.appInfo.backupAgentName; // full backup operation but no app-supplied agent? use the default implementation diff --git a/core/java/android/app/ForegroundServiceTypeException.java b/core/java/android/app/ForegroundServiceTypeException.java new file mode 100644 index 000000000000..9a9180efdaf6 --- /dev/null +++ b/core/java/android/app/ForegroundServiceTypeException.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.app; + +import android.annotation.NonNull; + +/** + * Base exception thrown when an app tries to start a foreground {@link Service} + * without a valid type. + */ +public abstract class ForegroundServiceTypeException extends ServiceStartNotAllowedException { + /** + * Constructor. + */ + public ForegroundServiceTypeException(@NonNull String message) { + super(message); + } +} diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java index e419e0602f2a..818bdc26523c 100644 --- a/core/java/android/app/ForegroundServiceTypePolicy.java +++ b/core/java/android/app/ForegroundServiceTypePolicy.java @@ -25,6 +25,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_D import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; +import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; @@ -153,6 +154,20 @@ public abstract class ForegroundServiceTypePolicy { public static final long FGS_TYPE_PERMISSION_CHANGE_ID = 254662522L; /** + * The policy for the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST}. + * + * @hide + */ + public static final @NonNull ForegroundServiceTypePolicyInfo FGS_TYPE_POLICY_MANIFEST = + new ForegroundServiceTypePolicyInfo( + FOREGROUND_SERVICE_TYPE_MANIFEST, + FGS_TYPE_NONE_DEPRECATION_CHANGE_ID, + FGS_TYPE_NONE_DISABLED_CHANGE_ID, + null, + null + ); + + /** * The policy for the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}. * * @hide @@ -954,6 +969,8 @@ public abstract class ForegroundServiceTypePolicy { * Constructor */ public DefaultForegroundServiceTypePolicy() { + mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_MANIFEST, + FGS_TYPE_POLICY_MANIFEST); mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_NONE, FGS_TYPE_POLICY_NONE); mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_DATA_SYNC, diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl index 62481ba8f251..8b655b9bf315 100644 --- a/core/java/android/app/IActivityClientController.aidl +++ b/core/java/android/app/IActivityClientController.aidl @@ -78,7 +78,11 @@ interface IActivityClientController { boolean willActivityBeVisible(in IBinder token); int getDisplayId(in IBinder activityToken); int getTaskForActivity(in IBinder token, in boolean onlyRoot); - int getTaskWindowingMode(in IBinder activityToken); + /** + * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if + * the task {@link Configuration} cannot be obtained. + */ + Configuration getTaskConfiguration(in IBinder activityToken); IBinder getActivityTokenBelow(IBinder token); ComponentName getCallingActivity(in IBinder token); String getCallingPackage(in IBinder token); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 7475ef8ec577..902f172b6ad7 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -304,7 +304,7 @@ interface IActivityManager { @UnsupportedAppUsage void resumeAppSwitches(); boolean bindBackupAgent(in String packageName, int backupRestoreMode, int targetUserId, - int operationType); + int backupDestination); void backupAgentCreated(in String packageName, in IBinder agent, int userId); void unbindBackupAgent(in ApplicationInfo appInfo); int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, diff --git a/core/java/android/app/ForegroundServiceTypeNotAllowedException.java b/core/java/android/app/InvalidForegroundServiceTypeException.java index c258242627c9..6ff02626d052 100644 --- a/core/java/android/app/ForegroundServiceTypeNotAllowedException.java +++ b/core/java/android/app/InvalidForegroundServiceTypeException.java @@ -20,18 +20,18 @@ import android.os.Parcel; import android.os.Parcelable; /** - * Exception thrown when an app tries to start a foreground {@link Service} without a valid type. + * Exception thrown when an app tries to start a foreground {@link Service} with an invalid type. */ -public final class ForegroundServiceTypeNotAllowedException - extends ServiceStartNotAllowedException implements Parcelable { +public final class InvalidForegroundServiceTypeException + extends ForegroundServiceTypeException implements Parcelable { /** * Constructor. */ - public ForegroundServiceTypeNotAllowedException(@NonNull String message) { + public InvalidForegroundServiceTypeException(@NonNull String message) { super(message); } - ForegroundServiceTypeNotAllowedException(@NonNull Parcel source) { + InvalidForegroundServiceTypeException(@NonNull Parcel source) { super(source.readString()); } @@ -45,17 +45,17 @@ public final class ForegroundServiceTypeNotAllowedException dest.writeString(getMessage()); } - public static final @NonNull Creator<android.app.ForegroundServiceTypeNotAllowedException> - CREATOR = new Creator<android.app.ForegroundServiceTypeNotAllowedException>() { + public static final @NonNull Creator<android.app.InvalidForegroundServiceTypeException> + CREATOR = new Creator<android.app.InvalidForegroundServiceTypeException>() { @NonNull - public android.app.ForegroundServiceTypeNotAllowedException createFromParcel( + public android.app.InvalidForegroundServiceTypeException createFromParcel( Parcel source) { - return new android.app.ForegroundServiceTypeNotAllowedException(source); + return new android.app.InvalidForegroundServiceTypeException(source); } @NonNull - public android.app.ForegroundServiceTypeNotAllowedException[] newArray(int size) { - return new android.app.ForegroundServiceTypeNotAllowedException[size]; + public android.app.InvalidForegroundServiceTypeException[] newArray(int size) { + return new android.app.InvalidForegroundServiceTypeException[size]; } }; } diff --git a/core/java/android/app/MissingForegroundServiceTypeException.java b/core/java/android/app/MissingForegroundServiceTypeException.java new file mode 100644 index 000000000000..c9b200699ac0 --- /dev/null +++ b/core/java/android/app/MissingForegroundServiceTypeException.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.app; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Exception thrown when an app tries to start a foreground {@link Service} without a type. + */ +public final class MissingForegroundServiceTypeException + extends ForegroundServiceTypeException implements Parcelable { + /** + * Constructor. + */ + public MissingForegroundServiceTypeException(@NonNull String message) { + super(message); + } + + MissingForegroundServiceTypeException(@NonNull Parcel source) { + super(source.readString()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(getMessage()); + } + + public static final @NonNull Creator<android.app.MissingForegroundServiceTypeException> + CREATOR = new Creator<android.app.MissingForegroundServiceTypeException>() { + @NonNull + public android.app.MissingForegroundServiceTypeException createFromParcel( + Parcel source) { + return new android.app.MissingForegroundServiceTypeException(source); + } + + @NonNull + public android.app.MissingForegroundServiceTypeException[] newArray(int size) { + return new android.app.MissingForegroundServiceTypeException[size]; + } + }; +} diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 291edbb74c35..6d7a161d1687 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -748,7 +748,12 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac * If the app targeting API is * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from * becoming foreground service due to background restriction. - * @throws ForegroundServiceTypeNotAllowedException + * @throws InvalidForegroundServiceTypeException + * If the app targeting API is + * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later, and the manifest attribute + * {@link android.R.attr#foregroundServiceType} is set to invalid types(i.e. + * {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}). + * @throws MissingForegroundServiceTypeException * If the app targeting API is * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later, and the manifest attribute * {@link android.R.attr#foregroundServiceType} is not set. @@ -761,7 +766,7 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac * {@link NotificationManager#notify(int, Notification) * NotificationManager.notify(int, Notification)}; must not be 0. * @param notification The Notification to be displayed. - * + * * @see #stopForeground(boolean) */ public final void startForeground(int id, Notification notification) { @@ -832,11 +837,16 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac * If the app targeting API is * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from * becoming foreground service due to background restriction. - * @throws ForegroundServiceTypeNotAllowedException + * @throws InvalidForegroundServiceTypeException + * If the app targeting API is + * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later, and the manifest attribute + * {@link android.R.attr#foregroundServiceType} or the param {@code foregroundServiceType} + * is set to invalid types(i.e.{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}). + * @throws MissingForegroundServiceTypeException * If the app targeting API is * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later, and the manifest attribute - * {@link android.R.attr#foregroundServiceType} is not set, or the param - * {@code foregroundServiceType} is {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}. + * {@link android.R.attr#foregroundServiceType} is not set and the param + * {@code foregroundServiceType} is set to {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST}. * @throws SecurityException If the app targeting API is * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later and doesn't have the * permission to start the foreground service with the specified type in diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e5cb0eaebdd3..e54a0841dd26 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -118,6 +118,7 @@ import android.location.CountryDetector; import android.location.ICountryDetector; import android.location.ILocationManager; import android.location.LocationManager; +import android.media.AudioDeviceVolumeManager; import android.media.AudioManager; import android.media.MediaFrameworkInitializer; import android.media.MediaFrameworkPlatformInitializer; @@ -209,6 +210,7 @@ import android.service.oemlock.OemLockManager; import android.service.persistentdata.IPersistentDataBlockService; import android.service.persistentdata.PersistentDataBlockManager; import android.service.vr.IVrManager; +import android.system.virtualmachine.VirtualizationFrameworkInitializer; import android.telecom.TelecomManager; import android.telephony.MmsManager; import android.telephony.TelephonyFrameworkInitializer; @@ -343,6 +345,13 @@ public final class SystemServiceRegistry { return new AudioManager(ctx); }}); + registerService(Context.AUDIO_DEVICE_VOLUME_SERVICE, AudioDeviceVolumeManager.class, + new CachedServiceFetcher<AudioDeviceVolumeManager>() { + @Override + public AudioDeviceVolumeManager createService(ContextImpl ctx) { + return new AudioDeviceVolumeManager(ctx); + }}); + registerService(Context.MEDIA_ROUTER_SERVICE, MediaRouter.class, new CachedServiceFetcher<MediaRouter>() { @Override @@ -1558,6 +1567,7 @@ public final class SystemServiceRegistry { NearbyFrameworkInitializer.registerServiceWrappers(); OnDevicePersonalizationFrameworkInitializer.registerServiceWrappers(); DeviceLockFrameworkInitializer.registerServiceWrappers(); + VirtualizationFrameworkInitializer.registerServiceWrappers(); } finally { // If any of the above code throws, we're in a pretty bad shape and the process // will likely crash, but we'll reset it just in case there's an exception handler... diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index b9a7186dcd2e..8685259217c5 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -1148,12 +1148,26 @@ public class WallpaperManager { * @return the dimensions of system wallpaper * @hide */ + @Nullable public Rect peekBitmapDimensions() { return sGlobals.peekWallpaperDimensions( mContext, true /* returnDefault */, mContext.getUserId()); } /** + * Peek the dimensions of given wallpaper of the user without decoding it. + * + * @param which Wallpaper type. Must be either {@link #FLAG_SYSTEM} or + * {@link #FLAG_LOCK}. + * @return the dimensions of system wallpaper + * @hide + */ + @Nullable + public Rect peekBitmapDimensions(@SetWallpaperFlags int which) { + return peekBitmapDimensions(); + } + + /** * Get an open, readable file descriptor to the given wallpaper image file. * The caller is responsible for closing the file descriptor when done ingesting the file. * diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index a4f612d7faee..e323e8967cc7 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -20,7 +20,8 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.app.IBackupAgent; import android.app.QueuedWork; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; +import android.app.backup.BackupAnnotations.OperationType; import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags; import android.content.Context; import android.content.ContextWrapper; @@ -137,7 +138,7 @@ import java.util.concurrent.CountDownLatch; public abstract class BackupAgent extends ContextWrapper { private static final String TAG = "BackupAgent"; private static final boolean DEBUG = false; - private static final int DEFAULT_OPERATION_TYPE = OperationType.BACKUP; + private static final int DEFAULT_BACKUP_DESTINATION = BackupDestination.CLOUD; /** @hide */ public static final int RESULT_SUCCESS = 0; @@ -207,7 +208,7 @@ public abstract class BackupAgent extends ContextWrapper { @Nullable private UserHandle mUser; // This field is written from the main thread (in onCreate), and read in a Binder thread (in // onFullBackup that is called from system_server via Binder). - @OperationType private volatile int mOperationType = DEFAULT_OPERATION_TYPE; + @BackupDestination private volatile int mBackupDestination = DEFAULT_BACKUP_DESTINATION; Handler getHandler() { if (mHandler == null) { @@ -265,28 +266,40 @@ public abstract class BackupAgent extends ContextWrapper { } /** + * Provided as a convenience for agent implementations that need an opportunity + * to do one-time initialization before the actual backup or restore operation + * is begun with information about the calling user. + * <p> + * * @hide */ public void onCreate(UserHandle user) { - onCreate(user, DEFAULT_OPERATION_TYPE); + onCreate(); } /** - * Provided as a convenience for agent implementations that need an opportunity - * to do one-time initialization before the actual backup or restore operation - * is begun with information about the calling user. - * <p> + * @deprecated Use {@link BackupAgent#onCreate(UserHandle, int, int)} instead. * * @hide */ - public void onCreate(UserHandle user, @OperationType int operationType) { - // TODO: Instantiate with the correct type using a parameter. - mLogger = new BackupRestoreEventLogger(BackupRestoreEventLogger.OperationType.BACKUP); + @Deprecated + public void onCreate(UserHandle user, @BackupDestination int backupDestination) { + mUser = user; + mBackupDestination = backupDestination; - onCreate(); + onCreate(user); + } + /** + * @hide + */ + public void onCreate(UserHandle user, @BackupDestination int backupDestination, + @OperationType int operationType) { mUser = user; - mOperationType = operationType; + mBackupDestination = backupDestination; + mLogger = new BackupRestoreEventLogger(operationType); + + onCreate(user, backupDestination); } /** @@ -433,7 +446,7 @@ public abstract class BackupAgent extends ContextWrapper { */ public void onFullBackup(FullBackupDataOutput data) throws IOException { FullBackup.BackupScheme backupScheme = FullBackup.getBackupScheme(this, - mOperationType); + mBackupDestination); if (!backupScheme.isFullBackupEnabled(data.getTransportFlags())) { return; } @@ -643,7 +656,7 @@ public abstract class BackupAgent extends ContextWrapper { if (includeMap == null || includeMap.size() == 0) { // Do entire sub-tree for the provided token. fullBackupFileTree(packageName, domainToken, - FullBackup.getBackupScheme(this, mOperationType) + FullBackup.getBackupScheme(this, mBackupDestination) .tokenToDirectoryPath(domainToken), filterSet, traversalExcludeSet, data); } else if (includeMap.get(domainToken) != null) { @@ -815,7 +828,7 @@ public abstract class BackupAgent extends ContextWrapper { ArraySet<String> systemExcludes, FullBackupDataOutput output) { // Pull out the domain and set it aside to use when making the tarball. - String domainPath = FullBackup.getBackupScheme(this, mOperationType) + String domainPath = FullBackup.getBackupScheme(this, mBackupDestination) .tokenToDirectoryPath(domain); if (domainPath == null) { // Should never happen. @@ -927,7 +940,7 @@ public abstract class BackupAgent extends ContextWrapper { } private boolean isFileEligibleForRestore(File destination) throws IOException { - FullBackup.BackupScheme bs = FullBackup.getBackupScheme(this, mOperationType); + FullBackup.BackupScheme bs = FullBackup.getBackupScheme(this, mBackupDestination); if (!bs.isFullRestoreEnabled()) { if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { Log.v(FullBackup.TAG_XML_PARSER, @@ -1001,7 +1014,7 @@ public abstract class BackupAgent extends ContextWrapper { + " domain=" + domain + " relpath=" + path + " mode=" + mode + " mtime=" + mtime); - basePath = FullBackup.getBackupScheme(this, mOperationType).tokenToDirectoryPath( + basePath = FullBackup.getBackupScheme(this, mBackupDestination).tokenToDirectoryPath( domain); if (domain.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) { mode = -1; // < 0 is a token to skip attempting a chmod() diff --git a/core/java/android/app/backup/BackupAnnotations.java b/core/java/android/app/backup/BackupAnnotations.java new file mode 100644 index 000000000000..d9228613cea6 --- /dev/null +++ b/core/java/android/app/backup/BackupAnnotations.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.backup; + +import android.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Annotations related to Android Backup&Restore. + * + * @hide + */ +public class BackupAnnotations { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + OperationType.UNKNOWN, + OperationType.BACKUP, + OperationType.RESTORE, + }) + public @interface OperationType { + int UNKNOWN = -1; + int BACKUP = 0; + int RESTORE = 1; + } + + /** + * Denotes where the backup data is going (e.g. to the cloud or directly to the other device) + * during backup or where it is coming from during restore. + * + * @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + BackupDestination.CLOUD, + BackupDestination.DEVICE_TRANSFER, + BackupDestination.ADB_BACKUP + }) + public @interface BackupDestination { + // A cloud backup. + int CLOUD = 0; + // A device to device migration. + int DEVICE_TRANSFER = 1; + // An adb backup. + int ADB_BACKUP = 2; + } +} diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java index d2c797255b0d..378020f5387d 100644 --- a/core/java/android/app/backup/BackupManager.java +++ b/core/java/android/app/backup/BackupManager.java @@ -200,22 +200,6 @@ public class BackupManager { @SystemApi public static final int ERROR_TRANSPORT_INVALID = -2; - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - OperationType.BACKUP, - OperationType.MIGRATION, - OperationType.ADB_BACKUP, - }) - public @interface OperationType { - // A backup / restore to / from an off-device location, e.g. cloud. - int BACKUP = 0; - // A direct transfer to another device. - int MIGRATION = 1; - // Backup via adb, data saved on the host machine. - int ADB_BACKUP = 3; - } - private Context mContext; @UnsupportedAppUsage private static IBackupManager sService; diff --git a/core/java/android/app/backup/BackupRestoreEventLogger.java b/core/java/android/app/backup/BackupRestoreEventLogger.java index 68740cb3c086..f89283377920 100644 --- a/core/java/android/app/backup/BackupRestoreEventLogger.java +++ b/core/java/android/app/backup/BackupRestoreEventLogger.java @@ -16,13 +16,13 @@ package android.app.backup; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; +import android.app.backup.BackupAnnotations.OperationType; import android.util.Slog; import java.lang.annotation.Retention; @@ -56,21 +56,6 @@ public class BackupRestoreEventLogger { public static final int DATA_TYPES_ALLOWED = 15; /** - * Operation types for which this logger can be used. - * - * @hide - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - OperationType.BACKUP, - OperationType.RESTORE - }) - @interface OperationType { - int BACKUP = 1; - int RESTORE = 2; - } - - /** * Denotes that the annotated element identifies a data type as required by the logging methods * of {@code BackupRestoreEventLogger} */ diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java index bf9a9b060b6b..637187120922 100644 --- a/core/java/android/app/backup/FullBackup.java +++ b/core/java/android/app/backup/FullBackup.java @@ -16,10 +16,9 @@ package android.app.backup; -import static android.app.backup.BackupManager.OperationType; - import android.annotation.Nullable; import android.annotation.StringDef; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; @@ -123,20 +122,20 @@ public class FullBackup { /** * Identify {@link BackupScheme} object by package and operation type - * (see {@link OperationType}) it corresponds to. + * (see {@link BackupDestination}) it corresponds to. */ private static class BackupSchemeId { final String mPackageName; - @OperationType final int mOperationType; + @BackupDestination final int mBackupDestination; - BackupSchemeId(String packageName, @OperationType int operationType) { + BackupSchemeId(String packageName, @BackupDestination int backupDestination) { mPackageName = packageName; - mOperationType = operationType; + mBackupDestination = backupDestination; } @Override public int hashCode() { - return Objects.hash(mPackageName, mOperationType); + return Objects.hash(mPackageName, mBackupDestination); } @Override @@ -149,7 +148,7 @@ public class FullBackup { } BackupSchemeId that = (BackupSchemeId) object; return Objects.equals(mPackageName, that.mPackageName) && - Objects.equals(mOperationType, that.mOperationType); + Objects.equals(mBackupDestination, that.mBackupDestination); } } @@ -164,19 +163,20 @@ public class FullBackup { new ArrayMap<>(); static synchronized BackupScheme getBackupScheme(Context context, - @OperationType int operationType) { - BackupSchemeId backupSchemeId = new BackupSchemeId(context.getPackageName(), operationType); + @BackupDestination int backupDestination) { + BackupSchemeId backupSchemeId = new BackupSchemeId(context.getPackageName(), + backupDestination); BackupScheme backupSchemeForPackage = kPackageBackupSchemeMap.get(backupSchemeId); if (backupSchemeForPackage == null) { - backupSchemeForPackage = new BackupScheme(context, operationType); + backupSchemeForPackage = new BackupScheme(context, backupDestination); kPackageBackupSchemeMap.put(backupSchemeId, backupSchemeForPackage); } return backupSchemeForPackage; } public static BackupScheme getBackupSchemeForTest(Context context) { - BackupScheme testing = new BackupScheme(context, OperationType.BACKUP); + BackupScheme testing = new BackupScheme(context, BackupDestination.CLOUD); testing.mExcludes = new ArraySet(); testing.mIncludes = new ArrayMap(); return testing; @@ -303,7 +303,7 @@ public class FullBackup { final int mDataExtractionRules; final int mFullBackupContent; - @OperationType final int mOperationType; + @BackupDestination final int mBackupDestination; final PackageManager mPackageManager; final StorageManager mStorageManager; final String mPackageName; @@ -426,12 +426,12 @@ public class FullBackup { */ ArraySet<PathWithRequiredFlags> mExcludes; - BackupScheme(Context context, @OperationType int operationType) { + BackupScheme(Context context, @BackupDestination int backupDestination) { ApplicationInfo applicationInfo = context.getApplicationInfo(); mDataExtractionRules = applicationInfo.dataExtractionRulesRes; mFullBackupContent = applicationInfo.fullBackupContent; - mOperationType = operationType; + mBackupDestination = backupDestination; mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); mPackageManager = context.getPackageManager(); mPackageName = context.getPackageName(); @@ -568,7 +568,7 @@ public class FullBackup { } try { - parseSchemeForOperationType(mOperationType); + parseSchemeForBackupDestination(mBackupDestination); } catch (PackageManager.NameNotFoundException e) { // Throw it as an IOException throw new IOException(e); @@ -576,12 +576,12 @@ public class FullBackup { } } - private void parseSchemeForOperationType(@OperationType int operationType) + private void parseSchemeForBackupDestination(@BackupDestination int backupDestination) throws PackageManager.NameNotFoundException, IOException, XmlPullParserException { - String configSection = getConfigSectionForOperationType(operationType); + String configSection = getConfigSectionForBackupDestination(backupDestination); if (configSection == null) { - Slog.w(TAG, "Given operation type isn't supported by backup scheme: " - + operationType); + Slog.w(TAG, "Given backup destination isn't supported by backup scheme: " + + backupDestination); return; } @@ -600,7 +600,7 @@ public class FullBackup { } } - if (operationType == OperationType.MIGRATION + if (backupDestination == BackupDestination.DEVICE_TRANSFER && CompatChanges.isChangeEnabled(IGNORE_FULL_BACKUP_CONTENT_IN_D2D)) { mIsUsingNewScheme = true; return; @@ -615,11 +615,12 @@ public class FullBackup { } @Nullable - private String getConfigSectionForOperationType(@OperationType int operationType) { - switch (operationType) { - case OperationType.BACKUP: + private String getConfigSectionForBackupDestination( + @BackupDestination int backupDestination) { + switch (backupDestination) { + case BackupDestination.CLOUD: return ConfigSection.CLOUD_BACKUP; - case OperationType.MIGRATION: + case BackupDestination.DEVICE_TRANSFER: return ConfigSection.DEVICE_TRANSFER; default: return null; diff --git a/core/java/android/app/time/LocationTimeZoneAlgorithmStatus.java b/core/java/android/app/time/LocationTimeZoneAlgorithmStatus.java index 710b8c40cefe..ec10d8431e74 100644 --- a/core/java/android/app/time/LocationTimeZoneAlgorithmStatus.java +++ b/core/java/android/app/time/LocationTimeZoneAlgorithmStatus.java @@ -16,8 +16,9 @@ package android.app.time; +import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_RUNNING; +import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED; import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_RUNNING; -import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_UNKNOWN; import static android.app.time.DetectorStatusTypes.detectionAlgorithmStatusFromString; import static android.app.time.DetectorStatusTypes.detectionAlgorithmStatusToString; import static android.app.time.DetectorStatusTypes.requireValidDetectionAlgorithmStatus; @@ -86,12 +87,24 @@ public final class LocationTimeZoneAlgorithmStatus implements Parcelable { public static final @ProviderStatus int PROVIDER_STATUS_IS_UNCERTAIN = 4; /** - * An instance that provides no information about algorithm status because the algorithm has not - * yet reported. Effectively a "null" status placeholder. + * An instance used when the location algorithm is not supported by the device. */ - @NonNull - public static final LocationTimeZoneAlgorithmStatus UNKNOWN = - new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_UNKNOWN, + public static final LocationTimeZoneAlgorithmStatus NOT_SUPPORTED = + new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED, + PROVIDER_STATUS_NOT_PRESENT, null, PROVIDER_STATUS_NOT_PRESENT, null); + + /** + * An instance used when the location algorithm is running, but has not reported an event. + */ + public static final LocationTimeZoneAlgorithmStatus RUNNING_NOT_REPORTED = + new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_NOT_RUNNING, + PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null); + + /** + * An instance used when the location algorithm is supported but not running. + */ + public static final LocationTimeZoneAlgorithmStatus NOT_RUNNING = + new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_NOT_RUNNING, PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null); private final @DetectionAlgorithmStatus int mStatus; diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index c14bb1beb025..91547016df8a 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -350,14 +350,72 @@ public final class VirtualDeviceManager { @VirtualDisplayFlag int flags, @Nullable @CallbackExecutor Executor executor, @Nullable VirtualDisplay.Callback callback) { - // TODO(b/205343547): Handle display groups properly instead of creating a new display - // group for every new virtual display created using this API. - // belongs to the same display group. VirtualDisplayConfig config = new VirtualDisplayConfig.Builder( getVirtualDisplayName(), width, height, densityDpi) .setSurface(surface) .setFlags(getVirtualDisplayFlags(flags)) .build(); + return createVirtualDisplayInternal(config, executor, callback); + } + + /** + * Creates a virtual display for this virtual device. All displays created on the same + * device belongs to the same display group. + * + * @param width The width of the virtual display in pixels, must be greater than 0. + * @param height The height of the virtual display in pixels, must be greater than 0. + * @param densityDpi The density of the virtual display in dpi, must be greater than 0. + * @param displayCategories The categories of the virtual display, indicating the type of + * activities allowed to run on the display. Activities can declare their type using + * {@link android.content.pm.ActivityInfo#targetDisplayCategory}. + * @param surface The surface to which the content of the virtual display should + * be rendered, or null if there is none initially. The surface can also be set later using + * {@link VirtualDisplay#setSurface(Surface)}. + * @param flags A combination of virtual display flags accepted by + * {@link DisplayManager#createVirtualDisplay}. In addition, the following flags are + * automatically set for all virtual devices: + * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC VIRTUAL_DISPLAY_FLAG_PUBLIC} and + * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY + * VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}. + * @param executor The executor on which {@code callback} will be invoked. This is ignored + * if {@code callback} is {@code null}. If {@code callback} is specified, this executor must + * not be null. + * @param callback Callback to call when the state of the {@link VirtualDisplay} changes + * @return The newly created virtual display, or {@code null} if the application could + * not create the virtual display. + * + * @see DisplayManager#createVirtualDisplay + */ + @Nullable + public VirtualDisplay createVirtualDisplay( + @IntRange(from = 1) int width, + @IntRange(from = 1) int height, + @IntRange(from = 1) int densityDpi, + @NonNull List<String> displayCategories, + @Nullable Surface surface, + @VirtualDisplayFlag int flags, + @Nullable @CallbackExecutor Executor executor, + @Nullable VirtualDisplay.Callback callback) { + VirtualDisplayConfig config = new VirtualDisplayConfig.Builder( + getVirtualDisplayName(), width, height, densityDpi) + .setDisplayCategories(displayCategories) + .setSurface(surface) + .setFlags(getVirtualDisplayFlags(flags)) + .build(); + return createVirtualDisplayInternal(config, executor, callback); + } + + /** + * @hide + */ + @Nullable + private VirtualDisplay createVirtualDisplayInternal( + @NonNull VirtualDisplayConfig config, + @Nullable @CallbackExecutor Executor executor, + @Nullable VirtualDisplay.Callback callback) { + // TODO(b/205343547): Handle display groups properly instead of creating a new display + // group for every new virtual display created using this API. + // belongs to the same display group. IVirtualDisplayCallback callbackWrapper = new DisplayManagerGlobal.VirtualDisplayCallback(callback, executor); final int displayId; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 59aad09a7b44..9f9fd3ceb5f7 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3850,6 +3850,7 @@ public abstract class Context { WIFI_RTT_RANGING_SERVICE, NSD_SERVICE, AUDIO_SERVICE, + AUDIO_DEVICE_VOLUME_SERVICE, AUTH_SERVICE, FINGERPRINT_SERVICE, //@hide: FACE_SERVICE, @@ -3938,6 +3939,7 @@ public abstract class Context { DISPLAY_HASH_SERVICE, CREDENTIAL_SERVICE, DEVICE_LOCK_SERVICE, + VIRTUALIZATION_SERVICE, }) @Retention(RetentionPolicy.SOURCE) public @interface ServiceName {} @@ -4693,6 +4695,18 @@ public abstract class Context { public static final String AUDIO_SERVICE = "audio"; /** + * @hide + * Use with {@link #getSystemService(String)} to retrieve a + * {@link android.media.AudioDeviceVolumeManager} for handling management of audio device + * (e.g. speaker, USB headset) volume. + * + * @see #getSystemService(String) + * @see android.media.AudioDeviceVolumeManager + */ + @SystemApi + public static final String AUDIO_DEVICE_VOLUME_SERVICE = "audio_device_volume"; + + /** * Use with {@link #getSystemService(String)} to retrieve a {@link * android.media.MediaTranscodingManager} for transcoding media. * @@ -6101,6 +6115,20 @@ public abstract class Context { public static final String DEVICE_LOCK_SERVICE = "device_lock"; /** + * Use with {@link #getSystemService(String)} to retrieve a + * {@link android.system.virtualmachine.VirtualMachineManager}. + * + * <p>On devices without {@link PackageManager#FEATURE_VIRTUALIZATION_FRAMEWORK} system feature + * the {@link #getSystemService(String)} will return {@code null}. + * + * @see #getSystemService(String) + * @see android.system.virtualmachine.VirtualMachineManager + * @hide + */ + @SystemApi + public static final String VIRTUALIZATION_SERVICE = "virtualization"; + + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. * @@ -6173,7 +6201,7 @@ public abstract class Context { */ @CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)") @PackageManager.PermissionResult - @PermissionMethod + @PermissionMethod(orSelf = true) public abstract int checkCallingOrSelfPermission(@NonNull @PermissionName String permission); /** @@ -6241,7 +6269,7 @@ public abstract class Context { * * @see #checkCallingOrSelfPermission(String) */ - @PermissionMethod + @PermissionMethod(orSelf = true) public abstract void enforceCallingOrSelfPermission( @NonNull @PermissionName String permission, @Nullable String message); diff --git a/core/java/android/content/pm/PermissionMethod.java b/core/java/android/content/pm/PermissionMethod.java index ba97342c5e3e..647c696b87f3 100644 --- a/core/java/android/content/pm/PermissionMethod.java +++ b/core/java/android/content/pm/PermissionMethod.java @@ -33,4 +33,20 @@ import java.lang.annotation.Target; */ @Retention(CLASS) @Target({METHOD}) -public @interface PermissionMethod {} +public @interface PermissionMethod { + /** + * Hard-coded list of permissions checked by this method + */ + @PermissionName String[] value() default {}; + /** + * If true, the check passes if the caller + * has any ONE of the supplied permissions + */ + boolean anyOf() default false; + /** + * Signifies that the permission check passes if + * the calling process OR the current process has + * the permission + */ + boolean orSelf() default false; +} diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java index 14f03eae8bf1..3b7ed07c41bc 100644 --- a/core/java/android/content/pm/ServiceInfo.java +++ b/core/java/android/content/pm/ServiceInfo.java @@ -106,7 +106,7 @@ public class ServiceInfo extends ComponentInfo * <p>Apps targeting API level {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and * later should NOT use this type, * calling {@link android.app.Service#startForeground(int, android.app.Notification, int)} with - * this type will get a {@link android.app.ForegroundServiceTypeNotAllowedException}.</p> + * this type will get a {@link android.app.InvalidForegroundServiceTypeException}.</p> * * @deprecated Do not use. */ @@ -124,7 +124,7 @@ public class ServiceInfo extends ComponentInfo * calling {@link android.app.Service#startForeground(int, android.app.Notification, int)} with * this type on devices running {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} is still * allowed, but calling it with this type on devices running future platform releases may get a - * {@link android.app.ForegroundServiceTypeNotAllowedException}.</p> + * {@link android.app.InvalidForegroundServiceTypeException}.</p> * * @deprecated Use {@link android.app.job.JobInfo.Builder} data transfer APIs instead. */ diff --git a/core/java/android/credentials/ClearCredentialStateRequest.aidl b/core/java/android/credentials/ClearCredentialStateRequest.aidl new file mode 100644 index 000000000000..2679ee45c313 --- /dev/null +++ b/core/java/android/credentials/ClearCredentialStateRequest.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.credentials; + +parcelable ClearCredentialStateRequest;
\ No newline at end of file diff --git a/core/java/android/credentials/ClearCredentialStateRequest.java b/core/java/android/credentials/ClearCredentialStateRequest.java new file mode 100644 index 000000000000..33afbed73815 --- /dev/null +++ b/core/java/android/credentials/ClearCredentialStateRequest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.credentials; + +import static java.util.Objects.requireNonNull; + +import android.annotation.NonNull; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.AnnotationValidations; + +/** + * A request class for clearing a user's credential state from the credential providers. + */ +public final class ClearCredentialStateRequest implements Parcelable { + + /** The request data. */ + @NonNull + private final Bundle mData; + + /** Returns the request data. */ + @NonNull + public Bundle getData() { + return mData; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeBundle(mData); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public String toString() { + return "ClearCredentialStateRequest {data=" + mData + "}"; + } + + /** + * Constructs a {@link ClearCredentialStateRequest}. + * + * @param data the request data + */ + public ClearCredentialStateRequest(@NonNull Bundle data) { + mData = requireNonNull(data, "data must not be null"); + } + + private ClearCredentialStateRequest(@NonNull Parcel in) { + Bundle data = in.readBundle(); + mData = data; + AnnotationValidations.validate(NonNull.class, null, mData); + } + + public static final @NonNull Creator<ClearCredentialStateRequest> CREATOR = + new Creator<ClearCredentialStateRequest>() { + @Override + public ClearCredentialStateRequest[] newArray(int size) { + return new ClearCredentialStateRequest[size]; + } + + @Override + public ClearCredentialStateRequest createFromParcel(@NonNull Parcel in) { + return new ClearCredentialStateRequest(in); + } + }; +} diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java index 04d57ad8993f..f9973a24b35f 100644 --- a/core/java/android/credentials/CredentialManager.java +++ b/core/java/android/credentials/CredentialManager.java @@ -142,18 +142,24 @@ public final class CredentialManager { } /** - * Clears the current user credential session from all credential providers. + * Clears the current user credential state from all credential providers. * - * <p>Usually invoked after your user signs out of your app so that they will not be - * automatically signed in the next time. + * You should invoked this api after your user signs out of your app to notify all credential + * providers that any stored credential session for the given app should be cleared. * + * A credential provider may have stored an active credential session and use it to limit + * sign-in options for future get-credential calls. For example, it may prioritize the active + * credential over any other available credential. When your user explicitly signs out of your + * app and in order to get the holistic sign-in options the next time, you should call this API + * to let the provider clear any stored credential session. + * + * @param request the request data * @param cancellationSignal an optional signal that allows for cancelling this call * @param executor the callback will take place on this {@link Executor} * @param callback the callback invoked when the request succeeds or fails - * - * @hide */ - public void clearCredentialSession( + public void clearCredentialState( + @NonNull ClearCredentialStateRequest request, @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<Void, CredentialManagerException> callback) { @@ -167,8 +173,8 @@ public final class CredentialManager { ICancellationSignal cancelRemote = null; try { - cancelRemote = mService.clearCredentialSession( - new ClearCredentialSessionTransport(executor, callback), + cancelRemote = mService.clearCredentialState(request, + new ClearCredentialStateTransport(executor, callback), mContext.getOpPackageName()); } catch (RemoteException e) { e.rethrowFromSystemServer(); @@ -255,14 +261,14 @@ public final class CredentialManager { } } - private static class ClearCredentialSessionTransport - extends IClearCredentialSessionCallback.Stub { + private static class ClearCredentialStateTransport + extends IClearCredentialStateCallback.Stub { // TODO: listen for cancellation to release callback. private final Executor mExecutor; private final OutcomeReceiver<Void, CredentialManagerException> mCallback; - private ClearCredentialSessionTransport(Executor executor, + private ClearCredentialStateTransport(Executor executor, OutcomeReceiver<Void, CredentialManagerException> callback) { mExecutor = executor; mCallback = callback; diff --git a/core/java/android/credentials/IClearCredentialSessionCallback.aidl b/core/java/android/credentials/IClearCredentialStateCallback.aidl index 903e7f56cd2e..f8b7ae440680 100644 --- a/core/java/android/credentials/IClearCredentialSessionCallback.aidl +++ b/core/java/android/credentials/IClearCredentialStateCallback.aidl @@ -17,11 +17,11 @@ package android.credentials; /** - * Listener for clearCredentialSession request. + * Listener for clearCredentialState request. * * @hide */ -interface IClearCredentialSessionCallback { +interface IClearCredentialStateCallback { oneway void onSuccess(); oneway void onError(int errorCode, String message); }
\ No newline at end of file diff --git a/core/java/android/credentials/ICredentialManager.aidl b/core/java/android/credentials/ICredentialManager.aidl index 35688d7fe113..c5497bdbdc0f 100644 --- a/core/java/android/credentials/ICredentialManager.aidl +++ b/core/java/android/credentials/ICredentialManager.aidl @@ -16,9 +16,10 @@ package android.credentials; +import android.credentials.ClearCredentialStateRequest; import android.credentials.CreateCredentialRequest; import android.credentials.GetCredentialRequest; -import android.credentials.IClearCredentialSessionCallback; +import android.credentials.IClearCredentialStateCallback; import android.credentials.ICreateCredentialCallback; import android.credentials.IGetCredentialCallback; import android.os.ICancellationSignal; @@ -34,5 +35,5 @@ interface ICredentialManager { @nullable ICancellationSignal executeCreateCredential(in CreateCredentialRequest request, in ICreateCredentialCallback callback, String callingPackage); - @nullable ICancellationSignal clearCredentialSession(in IClearCredentialSessionCallback callback, String callingPackage); + @nullable ICancellationSignal clearCredentialState(in ClearCredentialStateRequest request, in IClearCredentialStateCallback callback, String callingPackage); } diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 50551feed522..f858227a0f1d 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -245,11 +245,13 @@ public final class CameraManager { * applications is not guaranteed to be supported, however.</p> * * <p>For concurrent operation, in chronological order : - * - Applications must first close any open cameras that have sessions configured, using - * {@link CameraDevice#close}. - * - All camera devices intended to be operated concurrently, must be opened using - * {@link #openCamera}, before configuring sessions on any of the camera devices.</p> - * + * <ul> + * <li> Applications must first close any open cameras that have sessions configured, using + * {@link CameraDevice#close}. </li> + * <li> All camera devices intended to be operated concurrently, must be opened using + * {@link #openCamera}, before configuring sessions on any of the camera devices.</li> + *</ul> + *</p> * <p>Each device in a combination, is guaranteed to support stream combinations which may be * obtained by querying {@link #getCameraCharacteristics} for the key * {@link android.hardware.camera2.CameraCharacteristics#SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS}.</p> diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java index b76b98d3c37a..891ba364db2f 100644 --- a/core/java/android/hardware/display/VirtualDisplayConfig.java +++ b/core/java/android/hardware/display/VirtualDisplayConfig.java @@ -30,6 +30,9 @@ import android.view.Surface; import com.android.internal.util.DataClass; +import java.util.ArrayList; +import java.util.List; + /** * Holds configuration used to create {@link VirtualDisplay} instances. See * {@link MediaProjection#createVirtualDisplay(VirtualDisplayConfig, VirtualDisplay.Callback, Handler)}. @@ -99,6 +102,13 @@ public final class VirtualDisplayConfig implements Parcelable { */ private boolean mWindowManagerMirroring = false; + /** + * The display categories. If set, only corresponding activities from the same category can be + * shown on the display. + */ + @DataClass.PluralOf("displayCategory") + @NonNull private List<String> mDisplayCategories = new ArrayList<>(); + // Code below generated by codegen v1.0.23. @@ -124,7 +134,8 @@ public final class VirtualDisplayConfig implements Parcelable { @Nullable Surface surface, @Nullable String uniqueId, int displayIdToMirror, - boolean windowManagerMirroring) { + boolean windowManagerMirroring, + @NonNull List<String> displayCategories) { this.mName = name; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mName); @@ -147,6 +158,9 @@ public final class VirtualDisplayConfig implements Parcelable { this.mUniqueId = uniqueId; this.mDisplayIdToMirror = displayIdToMirror; this.mWindowManagerMirroring = windowManagerMirroring; + this.mDisplayCategories = displayCategories; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mDisplayCategories); // onConstructed(); // You can define this method to get a callback } @@ -233,6 +247,15 @@ public final class VirtualDisplayConfig implements Parcelable { return mWindowManagerMirroring; } + /** + * The display categories. If set, only corresponding activities from the same category can be + * shown on the display. + */ + @DataClass.Generated.Member + public @NonNull List<String> getDisplayCategories() { + return mDisplayCategories; + } + @Override @DataClass.Generated.Member public void writeToParcel(@NonNull Parcel dest, int flags) { @@ -252,6 +275,7 @@ public final class VirtualDisplayConfig implements Parcelable { if (mSurface != null) dest.writeTypedObject(mSurface, flags); if (mUniqueId != null) dest.writeString(mUniqueId); dest.writeInt(mDisplayIdToMirror); + dest.writeStringList(mDisplayCategories); } @Override @@ -275,6 +299,8 @@ public final class VirtualDisplayConfig implements Parcelable { Surface surface = (flg & 0x20) == 0 ? null : (Surface) in.readTypedObject(Surface.CREATOR); String uniqueId = (flg & 0x40) == 0 ? null : in.readString(); int displayIdToMirror = in.readInt(); + List<String> displayCategories = new ArrayList<>(); + in.readStringList(displayCategories); this.mName = name; com.android.internal.util.AnnotationValidations.validate( @@ -298,6 +324,9 @@ public final class VirtualDisplayConfig implements Parcelable { this.mUniqueId = uniqueId; this.mDisplayIdToMirror = displayIdToMirror; this.mWindowManagerMirroring = windowManagerMirroring; + this.mDisplayCategories = displayCategories; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mDisplayCategories); // onConstructed(); // You can define this method to get a callback } @@ -332,6 +361,7 @@ public final class VirtualDisplayConfig implements Parcelable { private @Nullable String mUniqueId; private int mDisplayIdToMirror; private boolean mWindowManagerMirroring; + private @NonNull List<String> mDisplayCategories; private long mBuilderFieldsSet = 0L; @@ -478,10 +508,30 @@ public final class VirtualDisplayConfig implements Parcelable { return this; } + /** + * The display categories. If set, only corresponding activities from the same category can be + * shown on the display. + */ + @DataClass.Generated.Member + public @NonNull Builder setDisplayCategories(@NonNull List<String> value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x200; + mDisplayCategories = value; + return this; + } + + /** @see #setDisplayCategories */ + @DataClass.Generated.Member + public @NonNull Builder addDisplayCategory(@NonNull String value) { + if (mDisplayCategories == null) setDisplayCategories(new ArrayList<>()); + mDisplayCategories.add(value); + return this; + } + /** Builds the instance. This builder should not be touched after calling this! */ public @NonNull VirtualDisplayConfig build() { checkNotUsed(); - mBuilderFieldsSet |= 0x200; // Mark builder used + mBuilderFieldsSet |= 0x400; // Mark builder used if ((mBuilderFieldsSet & 0x10) == 0) { mFlags = 0; @@ -498,6 +548,9 @@ public final class VirtualDisplayConfig implements Parcelable { if ((mBuilderFieldsSet & 0x100) == 0) { mWindowManagerMirroring = false; } + if ((mBuilderFieldsSet & 0x200) == 0) { + mDisplayCategories = new ArrayList<>(); + } VirtualDisplayConfig o = new VirtualDisplayConfig( mName, mWidth, @@ -507,12 +560,13 @@ public final class VirtualDisplayConfig implements Parcelable { mSurface, mUniqueId, mDisplayIdToMirror, - mWindowManagerMirroring); + mWindowManagerMirroring, + mDisplayCategories); return o; } private void checkNotUsed() { - if ((mBuilderFieldsSet & 0x200) != 0) { + if ((mBuilderFieldsSet & 0x400) != 0) { throw new IllegalStateException( "This Builder should not be reused. Use a new Builder instance instead"); } @@ -520,10 +574,10 @@ public final class VirtualDisplayConfig implements Parcelable { } @DataClass.Generated( - time = 1646227247934L, + time = 1668534501320L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java", - inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate @android.hardware.display.DisplayManager.VirtualDisplayFlag int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate int mDisplayIdToMirror\nprivate boolean mWindowManagerMirroring\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)") + inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate @android.hardware.display.DisplayManager.VirtualDisplayFlag int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate int mDisplayIdToMirror\nprivate boolean mWindowManagerMirroring\nprivate @com.android.internal.util.DataClass.PluralOf(\"displayCategory\") @android.annotation.NonNull java.util.List<java.lang.String> mDisplayCategories\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java index 3e509e4d1c2f..b0b7a416c019 100644 --- a/core/java/android/hardware/hdmi/HdmiControlManager.java +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java @@ -50,7 +50,7 @@ import java.util.stream.Collectors; /** * The {@link HdmiControlManager} class is used to send HDMI control messages - * to attached CEC devices. + * to attached CEC devices. It also allows to control the eARC feature. * * <p>Provides various HDMI client instances that represent HDMI-CEC logical devices * hosted in the system. {@link #getTvClient()}, for instance will return an @@ -398,6 +398,30 @@ public final class HdmiControlManager { @Retention(RetentionPolicy.SOURCE) public @interface RoutingControl {} + // -- Whether the Soundbar mode feature is enabled or disabled. + /** + * Soundbar mode feature enabled. + * + * @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE + */ + public static final int SOUNDBAR_MODE_ENABLED = 1; + /** + * Soundbar mode feature disabled. + * + * @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE + */ + public static final int SOUNDBAR_MODE_DISABLED = 0; + /** + * @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE + * @hide + */ + @IntDef(prefix = { "SOUNDBAR_MODE" }, value = { + SOUNDBAR_MODE_ENABLED, + SOUNDBAR_MODE_DISABLED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SoundbarMode {} + // -- Scope of CEC power control messages sent by a playback device. /** * Send CEC power control messages to TV only: @@ -775,6 +799,31 @@ public final class HdmiControlManager { @Retention(RetentionPolicy.SOURCE) public @interface SadPresenceInQuery {} + // -- Whether eARC is enabled or disabled. + /** + * eARC enabled. + * + * @see HdmiControlManager#SETTING_NAME_EARC_ENABLED + */ + public static final int EARC_FEATURE_ENABLED = 1; + /** + * eARC disabled. + * + * @see HdmiControlManager#SETTING_NAME_EARC_ENABLED + */ + public static final int EARC_FEATURE_DISABLED = 0; + /** + * @hide + * + * @see HdmiControlManager#SETTING_NAME_EARC_ENABLED + */ + @IntDef(prefix = { "EARC_FEATURE" }, value = { + EARC_FEATURE_ENABLED, + EARC_FEATURE_DISABLED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EarcFeature {} + // -- Settings available in the CEC Configuration. /** * Name of a setting deciding whether the CEC is enabled. @@ -795,6 +844,14 @@ public final class HdmiControlManager { */ public static final String CEC_SETTING_NAME_ROUTING_CONTROL = "routing_control"; /** + * Name of a setting deciding whether the Soundbar mode feature is enabled. + * Before exposing this setting make sure the hardware supports it, otherwise, you may + * experience multiple issues. + * + * @see HdmiControlManager#setSoundbarMode(int) + */ + public static final String CEC_SETTING_NAME_SOUNDBAR_MODE = "soundbar_mode"; + /** * Name of a setting deciding on the power control mode. * * @see HdmiControlManager#setPowerControlMode(String) @@ -1032,11 +1089,21 @@ public final class HdmiControlManager { */ public static final String CEC_SETTING_NAME_QUERY_SAD_MAX = "query_sad_max"; /** + * Name of a setting representing whether eARC is enabled or not. + * + * @see HdmiControlManager#setEarcEnabled(int) + */ + public static final String SETTING_NAME_EARC_ENABLED = "earc_enabled"; + /** * @hide */ - @StringDef(prefix = { "CEC_SETTING_NAME_" }, value = { + // TODO(b/240379115): change names of CEC settings so that their prefix matches with the other + // HDMI control settings. + @StringDef(value = { CEC_SETTING_NAME_HDMI_CEC_ENABLED, CEC_SETTING_NAME_HDMI_CEC_VERSION, + CEC_SETTING_NAME_ROUTING_CONTROL, + CEC_SETTING_NAME_SOUNDBAR_MODE, CEC_SETTING_NAME_POWER_CONTROL_MODE, CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, @@ -1066,8 +1133,9 @@ public final class HdmiControlManager { CEC_SETTING_NAME_QUERY_SAD_DST, CEC_SETTING_NAME_QUERY_SAD_WMAPRO, CEC_SETTING_NAME_QUERY_SAD_MAX, + SETTING_NAME_EARC_ENABLED, }) - public @interface CecSettingName {} + public @interface SettingName {} /** * @hide @@ -1188,7 +1256,16 @@ public final class HdmiControlManager { case HdmiDeviceInfo.DEVICE_PLAYBACK: return mHasPlaybackDevice ? new HdmiPlaybackClient(mService) : null; case HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM: - return mHasAudioSystemDevice ? new HdmiAudioSystemClient(mService) : null; + try { + if ((mService.getCecSettingIntValue(CEC_SETTING_NAME_SOUNDBAR_MODE) + == SOUNDBAR_MODE_ENABLED && mHasPlaybackDevice) + || mHasAudioSystemDevice) { + return new HdmiAudioSystemClient(mService); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + return null; case HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH: return (mHasSwitchDevice || mIsSwitchDevice) ? new HdmiSwitchClient(mService) : null; @@ -1291,6 +1368,22 @@ public final class HdmiControlManager { } /** + * Get the list of the HDMI ports configuration. + * + * <p>This returns an empty list when the current device does not have HDMI ports. + * + * @return a list of {@link HdmiPortInfo} + */ + @NonNull + public List<HdmiPortInfo> getPortInfo() { + try { + return mService.getPortInfo(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Power off the target device by sending CEC commands. Note that this device can't be the * current device itself. * @@ -1685,7 +1778,7 @@ public final class HdmiControlManager { public void addHotplugEventListener(@NonNull @CallbackExecutor Executor executor, @NonNull HotplugEventListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "addHotplugEventListener: HdmiControlService is not available"); return; } if (mHotplugEventListeners.containsKey(listener)) { @@ -1710,7 +1803,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void removeHotplugEventListener(HotplugEventListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "removeHotplugEventListener: HdmiControlService is not available"); return; } IHdmiHotplugEventListener wrappedListener = mHotplugEventListeners.remove(listener); @@ -1778,7 +1871,7 @@ public final class HdmiControlManager { public void addHdmiControlStatusChangeListener(@NonNull @CallbackExecutor Executor executor, @NonNull HdmiControlStatusChangeListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "addHdmiControlStatusChangeListener: HdmiControlService is not available"); return; } if (mHdmiControlStatusChangeListeners.containsKey(listener)) { @@ -1805,7 +1898,8 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void removeHdmiControlStatusChangeListener(HdmiControlStatusChangeListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, + "removeHdmiControlStatusChangeListener: HdmiControlService is not available"); return; } IHdmiControlStatusChangeListener wrappedListener = @@ -1854,7 +1948,8 @@ public final class HdmiControlManager { public void addHdmiCecVolumeControlFeatureListener(@NonNull @CallbackExecutor Executor executor, @NonNull HdmiCecVolumeControlFeatureListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, + "addHdmiCecVolumeControlFeatureListener: HdmiControlService is not available"); return; } if (mHdmiCecVolumeControlFeatureListeners.containsKey(listener)) { @@ -1882,7 +1977,9 @@ public final class HdmiControlManager { public void removeHdmiCecVolumeControlFeatureListener( HdmiCecVolumeControlFeatureListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, + "removeHdmiCecVolumeControlFeatureListener: HdmiControlService is not " + + "available"); return; } IHdmiCecVolumeControlFeatureListener wrappedListener = @@ -1922,7 +2019,7 @@ public final class HdmiControlManager { * * @param setting name of a CEC setting that changed */ - void onChange(@NonNull @CecSettingName String setting); + void onChange(@NonNull @SettingName String setting); } private final ArrayMap<String, @@ -1930,11 +2027,11 @@ public final class HdmiControlManager { mCecSettingChangeListeners = new ArrayMap<>(); private void addCecSettingChangeListener( - @NonNull @CecSettingName String setting, + @NonNull @SettingName String setting, @NonNull @CallbackExecutor Executor executor, @NonNull CecSettingChangeListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "addCecSettingChangeListener: HdmiControlService is not available"); return; } if (mCecSettingChangeListeners.containsKey(setting) @@ -1956,10 +2053,10 @@ public final class HdmiControlManager { } private void removeCecSettingChangeListener( - @NonNull @CecSettingName String setting, + @NonNull @SettingName String setting, @NonNull CecSettingChangeListener listener) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "removeCecSettingChangeListener: HdmiControlService is not available"); return; } IHdmiCecSettingChangeListener wrappedListener = @@ -1992,17 +2089,20 @@ public final class HdmiControlManager { } /** - * Get a set of user-modifiable settings. + * Get a set of user-modifiable HDMI control settings. + * This applies to CEC settings and eARC settings. * * @return a set of user-modifiable settings. * @throws RuntimeException when the HdmiControlService is not available. */ + // TODO(b/240379115): rename this API to represent that this applies to all HDMI control + // settings and not just CEC settings. @NonNull - @CecSettingName + @SettingName @RequiresPermission(android.Manifest.permission.HDMI_CEC) public List<String> getUserCecSettings() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getUserCecSettings: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2013,7 +2113,9 @@ public final class HdmiControlManager { } /** - * Get a set of allowed values for a setting (string value-type). + * Get a set of allowed values for an HDMI control setting (string value-type). + * This applies to CEC settings and eARC settings. + * * * @param name name of the setting * @return a set of allowed values for a settings. {@code null} on failure. @@ -2021,11 +2123,13 @@ public final class HdmiControlManager { * @throws IllegalArgumentException when setting {@code name} value type is invalid. * @throws RuntimeException when the HdmiControlService is not available. */ + // TODO(b/240379115): rename this API to represent that this applies to all HDMI control + // settings and not just CEC settings. @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) - public List<String> getAllowedCecSettingStringValues(@NonNull @CecSettingName String name) { + public List<String> getAllowedCecSettingStringValues(@NonNull @SettingName String name) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getAllowedCecSettingStringValues: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2036,7 +2140,8 @@ public final class HdmiControlManager { } /** - * Get a set of allowed values for a setting (int value-type). + * Get a set of allowed values for an HDMI control setting (int value-type). + * This applies to CEC settings and eARC settings. * * @param name name of the setting * @return a set of allowed values for a settings. {@code null} on failure. @@ -2044,11 +2149,13 @@ public final class HdmiControlManager { * @throws IllegalArgumentException when setting {@code name} value type is invalid. * @throws RuntimeException when the HdmiControlService is not available. */ + // TODO(b/240379115): rename this API to represent that this applies to all HDMI control + // settings and not just CEC settings. @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) - public List<Integer> getAllowedCecSettingIntValues(@NonNull @CecSettingName String name) { + public List<Integer> getAllowedCecSettingIntValues(@NonNull @SettingName String name) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getAllowedCecSettingIntValues: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2067,7 +2174,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecEnabled(@NonNull @HdmiCecControl int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setHdmiCecEnabled: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2087,7 +2194,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecEnabled() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getHdmiCecEnabled: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2145,7 +2252,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecVersion(@NonNull @HdmiCecVersion int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setHdmiCecVersion: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2167,7 +2274,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecVersion() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getHdmiCecVersion: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2190,7 +2297,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setRoutingControl(@NonNull @RoutingControl int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setRoutingControl: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2215,7 +2322,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getRoutingControl() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getRoutingControl: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2226,6 +2333,54 @@ public final class HdmiControlManager { } /** + * Set the status of Soundbar mode feature. + * + * <p>This allows to enable/disable Soundbar mode on the playback device. + * The setting's effect will be available on devices where the hardware supports this feature. + * If enabled, an audio system local device will be allocated and try to establish an ARC + * connection with the TV. If disabled, the ARC connection will be terminated and the audio + * system local device will be removed from the network. + * + * @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE + */ + @RequiresPermission(android.Manifest.permission.HDMI_CEC) + public void setSoundbarMode(@SoundbarMode int value) { + if (mService == null) { + Log.e(TAG, "setSoundbarMode: HdmiControlService is not available"); + throw new RuntimeException("HdmiControlService is not available"); + } + try { + mService.setCecSettingIntValue(CEC_SETTING_NAME_SOUNDBAR_MODE, value); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Get the current status of Soundbar mode feature. + * + * <p>Reflects whether Soundbar mode is currently enabled on the playback device. + * If enabled, an audio system local device will be allocated and try to establish an ARC + * connection with the TV. If disabled, the ARC connection will be terminated and the audio + * system local device will be removed from the network. + * + * @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE + */ + @SoundbarMode + @RequiresPermission(android.Manifest.permission.HDMI_CEC) + public int getSoundbarMode() { + if (mService == null) { + Log.e(TAG, "getSoundbarMode: HdmiControlService is not available"); + throw new RuntimeException("HdmiControlService is not available"); + } + try { + return mService.getCecSettingIntValue(CEC_SETTING_NAME_SOUNDBAR_MODE); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Set the status of Power Control. * * <p>Specifies to which devices Power Control messages should be sent: @@ -2236,7 +2391,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setPowerControlMode(@NonNull @PowerControlMode String value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setPowerControlMode: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2259,7 +2414,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerControlMode() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getPowerControlMode: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2280,7 +2435,8 @@ public final class HdmiControlManager { public void setPowerStateChangeOnActiveSourceLost( @NonNull @ActiveSourceLostBehavior String value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, + "setPowerStateChangeOnActiveSourceLost: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2303,7 +2459,8 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerStateChangeOnActiveSourceLost() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, + "getPowerStateChangeOnActiveSourceLost: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2328,7 +2485,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioControl(@NonNull @SystemAudioControl int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setSystemAudioControl: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2354,7 +2511,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioControl() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getSystemAudioControl: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2374,7 +2531,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioModeMuting(@NonNull @SystemAudioModeMuting int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setSystemAudioModeMuting: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2396,7 +2553,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioModeMuting() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getSystemAudioModeMuting: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2417,7 +2574,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvWakeOnOneTouchPlay(@NonNull @TvWakeOnOneTouchPlay int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setTvWakeOnOneTouchPlay: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2440,7 +2597,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getTvWakeOnOneTouchPlay() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getTvWakeOnOneTouchPlay: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2461,7 +2618,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvSendStandbyOnSleep(@NonNull @TvSendStandbyOnSleep int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setTvSendStandbyOnSleep: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2484,7 +2641,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getTvSendStandbyOnSleep() { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getTvSendStandbyOnSleep: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2516,7 +2673,7 @@ public final class HdmiControlManager { public void setSadPresenceInQuery(@NonNull @CecSettingSad String setting, @SadPresenceInQuery int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setSadPresenceInQuery: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2550,7 +2707,7 @@ public final class HdmiControlManager { public void setSadsPresenceInQuery(@NonNull @CecSettingSad List<String> settings, @SadPresenceInQuery int value) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "setSadsPresenceInQuery: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2582,7 +2739,7 @@ public final class HdmiControlManager { @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSadPresenceInQuery(@NonNull @CecSettingSad String setting) { if (mService == null) { - Log.e(TAG, "HdmiControlService is not available"); + Log.e(TAG, "getSadPresenceInQuery: HdmiControlService is not available"); throw new RuntimeException("HdmiControlService is not available"); } try { @@ -2591,4 +2748,44 @@ public final class HdmiControlManager { throw e.rethrowFromSystemServer(); } } + + /** + * Set the global status of eARC. + * + * <p>This allows to enable/disable the eARC feature on the device. If the feature is enabled + * and the hardware supports eARC as well, the device can attempt to establish an eARC + * connection. + */ + @RequiresPermission(android.Manifest.permission.HDMI_CEC) + public void setEarcEnabled(@NonNull @EarcFeature int value) { + if (mService == null) { + Log.e(TAG, "setEarcEnabled: HdmiControlService is not available"); + throw new RuntimeException("HdmiControlService is not available"); + } + try { + mService.setCecSettingIntValue(SETTING_NAME_EARC_ENABLED, value); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Get the current global status of eARC. + * + * <p>Reflects whether the eARC feature is currently enabled on the device. + */ + @NonNull + @EarcFeature + @RequiresPermission(android.Manifest.permission.HDMI_CEC) + public int getEarcEnabled() { + if (mService == null) { + Log.e(TAG, "getEarcEnabled: HdmiControlService is not available"); + throw new RuntimeException("HdmiControlService is not available"); + } + try { + return mService.getCecSettingIntValue(SETTING_NAME_EARC_ENABLED); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/hardware/hdmi/HdmiSwitchClient.java b/core/java/android/hardware/hdmi/HdmiSwitchClient.java index 0fb5894dc4d9..8aaeec3a98fe 100644 --- a/core/java/android/hardware/hdmi/HdmiSwitchClient.java +++ b/core/java/android/hardware/hdmi/HdmiSwitchClient.java @@ -184,7 +184,10 @@ public class HdmiSwitchClient extends HdmiClient { * <p>This returns an empty list when the current device does not have HDMI input. * * @return a list of {@link HdmiPortInfo} + * + * @deprecated Please use {@link HdmiControlManager#getPortInfo()} instead. */ + @Deprecated @NonNull public List<HdmiPortInfo> getPortInfo() { try { diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index fd3d1ac09e3f..bdcbcaacfae4 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -80,14 +80,30 @@ interface IInputManager { // Keyboard layouts configuration. KeyboardLayout[] getKeyboardLayouts(); + KeyboardLayout[] getKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier); + KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor); + String getCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier); + + @EnforcePermission("SET_KEYBOARD_LAYOUT") + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.SET_KEYBOARD_LAYOUT)") void setCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier, String keyboardLayoutDescriptor); + String[] getEnabledKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier); + + @EnforcePermission("SET_KEYBOARD_LAYOUT") + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.SET_KEYBOARD_LAYOUT)") void addKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier, String keyboardLayoutDescriptor); + + @EnforcePermission("SET_KEYBOARD_LAYOUT") + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.SET_KEYBOARD_LAYOUT)") void removeKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier, String keyboardLayoutDescriptor); diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index bf4fc4a72fdc..fb66cb9cfcc6 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -2766,12 +2766,12 @@ public class InputMethodService extends AbstractInputMethodService { return false; } if ((flags&InputMethod.SHOW_EXPLICIT) == 0) { - if (!configChange && onEvaluateFullscreenMode()) { + if (!configChange && onEvaluateFullscreenMode() && !isInputViewShown()) { // Don't show if this is not explicitly requested by the user and - // the input method is fullscreen. That would be too disruptive. - // However, we skip this change for a config change, since if - // the IME is already shown we do want to go into fullscreen - // mode at this point. + // the input method is fullscreen unless it is already shown. That + // would be too disruptive. However, we skip this change for a + // config change, since if the IME is already shown we do want to + // go into fullscreen mode at this point. return false; } if (!mSettingsObserver.shouldShowImeWithHardKeyboard() && diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 19e7bd4e748b..ca88ae306c59 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -262,6 +262,14 @@ public final class DeviceConfig { public static final String NAMESPACE_GAME_DRIVER = "game_driver"; /** + * Namespace for all HDMI Control features. + * + * @hide + */ + @SystemApi + public static final String NAMESPACE_HDMI_CONTROL = "hdmi_control"; + + /** * Namespace for all input-related features that are used at the native level. * These features are applied at reboot. * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 80098d56ebbc..630ad6c31560 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7898,6 +7898,13 @@ public final class Settings { "high_text_contrast_enabled"; /** + * The color contrast, float in [-1, 1], 1 being the highest contrast. + * + * @hide + */ + public static final String CONTRAST_LEVEL = "contrast_level"; + + /** * Setting that specifies whether the display magnification is enabled via a system-wide * triple tap gesture. Display magnifications allows the user to zoom in the display content * and is targeted to low vision users. The current magnification scale is controlled by diff --git a/core/java/android/service/voice/HotwordAudioStream.java b/core/java/android/service/voice/HotwordAudioStream.java index bf8ee47261fd..1c57700d38e1 100644 --- a/core/java/android/service/voice/HotwordAudioStream.java +++ b/core/java/android/service/voice/HotwordAudioStream.java @@ -92,41 +92,6 @@ public final class HotwordAudioStream implements Parcelable { return new PersistableBundle(); } - private String timestampToString() { - if (mTimestamp == null) { - return ""; - } - return "TimeStamp:" - + " framePos=" + mTimestamp.framePosition - + " nanoTime=" + mTimestamp.nanoTime; - } - - private void parcelTimestamp(Parcel dest, int flags) { - if (mTimestamp != null) { - // mTimestamp is not null, we write it to the parcel, set true. - dest.writeBoolean(true); - dest.writeLong(mTimestamp.framePosition); - dest.writeLong(mTimestamp.nanoTime); - } else { - // mTimestamp is null, we don't write any value out, set false. - dest.writeBoolean(false); - } - } - - @Nullable - private static AudioTimestamp unparcelTimestamp(Parcel in) { - // If it is true, it means we wrote the value to the parcel before, parse it. - // Otherwise, return null. - if (in.readBoolean()) { - final AudioTimestamp timeStamp = new AudioTimestamp(); - timeStamp.framePosition = in.readLong(); - timeStamp.nanoTime = in.readLong(); - return timeStamp; - } else { - return null; - } - } - /** * Provides an instance of {@link Builder} with state corresponding to this instance. * @hide @@ -229,7 +194,7 @@ public final class HotwordAudioStream implements Parcelable { return "HotwordAudioStream { " + "audioFormat = " + mAudioFormat + ", " + "audioStreamParcelFileDescriptor = " + mAudioStreamParcelFileDescriptor + ", " + - "timestamp = " + timestampToString() + ", " + + "timestamp = " + mTimestamp + ", " + "metadata = " + mMetadata + " }"; } @@ -278,7 +243,7 @@ public final class HotwordAudioStream implements Parcelable { dest.writeByte(flg); dest.writeTypedObject(mAudioFormat, flags); dest.writeTypedObject(mAudioStreamParcelFileDescriptor, flags); - parcelTimestamp(dest, flags); + if (mTimestamp != null) dest.writeTypedObject(mTimestamp, flags); dest.writeTypedObject(mMetadata, flags); } @@ -296,7 +261,7 @@ public final class HotwordAudioStream implements Parcelable { byte flg = in.readByte(); AudioFormat audioFormat = (AudioFormat) in.readTypedObject(AudioFormat.CREATOR); ParcelFileDescriptor audioStreamParcelFileDescriptor = (ParcelFileDescriptor) in.readTypedObject(ParcelFileDescriptor.CREATOR); - AudioTimestamp timestamp = unparcelTimestamp(in); + AudioTimestamp timestamp = (flg & 0x4) == 0 ? null : (AudioTimestamp) in.readTypedObject(AudioTimestamp.CREATOR); PersistableBundle metadata = (PersistableBundle) in.readTypedObject(PersistableBundle.CREATOR); this.mAudioFormat = audioFormat; @@ -449,10 +414,10 @@ public final class HotwordAudioStream implements Parcelable { } @DataClass.Generated( - time = 1666342101364L, + time = 1669184301563L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/service/voice/HotwordAudioStream.java", - inputSignatures = "private final @android.annotation.NonNull android.media.AudioFormat mAudioFormat\nprivate final @android.annotation.NonNull android.os.ParcelFileDescriptor mAudioStreamParcelFileDescriptor\nprivate final @android.annotation.Nullable android.media.AudioTimestamp mTimestamp\nprivate final @android.annotation.NonNull android.os.PersistableBundle mMetadata\nprivate static android.media.AudioTimestamp defaultTimestamp()\nprivate static android.os.PersistableBundle defaultMetadata()\nprivate java.lang.String timestampToString()\nprivate void parcelTimestamp(android.os.Parcel,int)\nprivate static @android.annotation.Nullable android.media.AudioTimestamp unparcelTimestamp(android.os.Parcel)\npublic android.service.voice.HotwordAudioStream.Builder buildUpon()\nclass HotwordAudioStream extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genParcelable=true, genToString=true)") + inputSignatures = "private final @android.annotation.NonNull android.media.AudioFormat mAudioFormat\nprivate final @android.annotation.NonNull android.os.ParcelFileDescriptor mAudioStreamParcelFileDescriptor\nprivate final @android.annotation.Nullable android.media.AudioTimestamp mTimestamp\nprivate final @android.annotation.NonNull android.os.PersistableBundle mMetadata\nprivate static android.media.AudioTimestamp defaultTimestamp()\nprivate static android.os.PersistableBundle defaultMetadata()\npublic android.service.voice.HotwordAudioStream.Builder buildUpon()\nclass HotwordAudioStream extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genParcelable=true, genToString=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index e5c9adba46a9..09d0fc5fe59a 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -26,7 +26,6 @@ import android.os.Build; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; -import android.telephony.Annotation.CallState; import android.telephony.Annotation.DisconnectCauses; import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; @@ -726,7 +725,7 @@ public class PhoneStateListener { */ @Deprecated @RequiresPermission(value = android.Manifest.permission.READ_PHONE_STATE, conditional = true) - public void onCallStateChanged(@CallState int state, String phoneNumber) { + public void onCallStateChanged(@Annotation.CallState int state, String phoneNumber) { // default implementation empty } @@ -1569,12 +1568,48 @@ public class PhoneStateListener { () -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state))); } - public void onCallAttributesChanged(CallAttributes callAttributes) { + public void onCallStatesChanged(List<CallState> callStateList) { PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); if (psl == null) return; + if (callStateList == null) return; + CallAttributes ca; + if (callStateList.isEmpty()) { + ca = new CallAttributes( + new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_IDLE, + PreciseCallState.PRECISE_CALL_STATE_IDLE, + PreciseCallState.PRECISE_CALL_STATE_IDLE, + DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID), + TelephonyManager.NETWORK_TYPE_UNKNOWN, new CallQuality()); + } else { + int foregroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; + int backgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; + int ringingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; + for (CallState cs : callStateList) { + switch (cs.getCallClassification()) { + case CallState.CALL_CLASSIFICATION_FOREGROUND: + foregroundCallState = cs.getCallState(); + break; + case CallState.CALL_CLASSIFICATION_BACKGROUND: + backgroundCallState = cs.getCallState(); + break; + case CallState.CALL_CLASSIFICATION_RINGING: + ringingCallState = cs.getCallState(); + break; + default: + break; + } + } + ca = new CallAttributes( + new PreciseCallState( + foregroundCallState, backgroundCallState, ringingCallState, + DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID), + callStateList.get(0).getNetworkType(), + callStateList.get(0).getCallQuality()); + } Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes))); + () -> mExecutor.execute( + () -> psl.onCallAttributesChanged(ca))); } public void onActiveDataSubIdChanged(int subId) { diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java index e8960b8e35cd..54c4b668bfb3 100644 --- a/core/java/android/telephony/TelephonyCallback.java +++ b/core/java/android/telephony/TelephonyCallback.java @@ -27,6 +27,7 @@ import android.os.Binder; import android.os.Build; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IPhoneStateListener; @@ -62,7 +63,7 @@ import java.util.concurrent.Executor; * appropriate sub-interfaces. */ public class TelephonyCallback { - + private static final String LOG_TAG = "TelephonyCallback"; /** * Experiment flag to set the per-pid registration limit for TelephonyCallback * @@ -1332,7 +1333,9 @@ public class TelephonyCallback { @SystemApi public interface CallAttributesListener { /** - * Callback invoked when the call attributes changes on the registered subscription. + * Callback invoked when the call attributes changes on the active call on the registered + * subscription. If the user swaps between a foreground and background call the call + * attributes will be reported for the active call only. * Note, the registration subscription ID comes from {@link TelephonyManager} object * which registers TelephonyCallback by * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. @@ -1346,9 +1349,77 @@ public class TelephonyCallback { * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}. * * @param callAttributes the call attributes + * @deprecated Use onCallStatesChanged({@link List<CallState>}) to get each of call + * state for all ongoing calls on the subscription. */ @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) - void onCallAttributesChanged(@NonNull CallAttributes callAttributes); + @Deprecated + default void onCallAttributesChanged(@NonNull CallAttributes callAttributes) { + Log.w(LOG_TAG, "onCallAttributesChanged(List<CallAttributes>) should be " + + "overridden."); + } + + /** + * Callback invoked when the call attributes changes on the ongoing calls on the registered + * subscription. If there are 1 foreground and 1 background call, Two {@link CallState} + * will be passed. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * In the event that there are no active(state is not + * {@link PreciseCallState#PRECISE_CALL_STATE_IDLE}) calls, this API will report empty list. + * + * The calling app should have carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}) if it does not have the + * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}. + * + * @param callStateList the list of call states for each ongoing call. If there are + * a active call and a holding call, 1 call attributes for + * {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE} and another + * for {@link PreciseCallState#PRECISE_CALL_STATE_HOLDING} + * will be in this list. + */ + // Added as default for backward compatibility + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + default void onCallStatesChanged(@NonNull List<CallState> callStateList) { + if (callStateList.size() > 0) { + int foregroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; + int backgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; + int ringingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; + for (CallState cs : callStateList) { + switch (cs.getCallClassification()) { + case CallState.CALL_CLASSIFICATION_FOREGROUND: + foregroundCallState = cs.getCallState(); + break; + case CallState.CALL_CLASSIFICATION_BACKGROUND: + backgroundCallState = cs.getCallState(); + break; + case CallState.CALL_CLASSIFICATION_RINGING: + ringingCallState = cs.getCallState(); + break; + default: + break; + } + } + onCallAttributesChanged(new CallAttributes( + new PreciseCallState( + ringingCallState, foregroundCallState, backgroundCallState, + DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID), + callStateList.get(0).getNetworkType(), + callStateList.get(0).getCallQuality())); + } else { + onCallAttributesChanged(new CallAttributes( + new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_IDLE, + PreciseCallState.PRECISE_CALL_STATE_IDLE, + PreciseCallState.PRECISE_CALL_STATE_IDLE, + DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID), + TelephonyManager.NETWORK_TYPE_UNKNOWN, new CallQuality())); + } + } } /** @@ -1702,14 +1773,13 @@ public class TelephonyCallback { () -> mExecutor.execute(() -> listener.onRadioPowerStateChanged(state))); } - public void onCallAttributesChanged(CallAttributes callAttributes) { + public void onCallStatesChanged(List<CallState> callStateList) { CallAttributesListener listener = (CallAttributesListener) mTelephonyCallbackWeakRef.get(); if (listener == null) return; Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> listener.onCallAttributesChanged( - callAttributes))); + () -> mExecutor.execute(() -> listener.onCallStatesChanged(callStateList))); } public void onActiveDataSubIdChanged(int subId) { diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index a3696e398668..0a1538de9f5d 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -32,13 +32,13 @@ import android.telephony.Annotation.CallState; import android.telephony.Annotation.DataActivityType; import android.telephony.Annotation.DisconnectCauses; import android.telephony.Annotation.NetworkType; -import android.telephony.Annotation.PreciseCallStates; import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; import android.telephony.TelephonyManager.CarrierPrivilegesCallback; import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsCallSession; import android.telephony.ims.ImsReasonInfo; import android.util.ArraySet; import android.util.Log; @@ -741,17 +741,20 @@ public class TelephonyRegistryManager { * @param slotIndex for which precise call state changed. Can be derived from subId except when * subId is invalid. * @param subId for which precise call state changed. - * @param ringCallPreciseState ringCall state. - * @param foregroundCallPreciseState foreground call state. - * @param backgroundCallPreciseState background call state. + * @param callStates Array of PreciseCallState of foreground, background & ringing calls. + * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId} for + * ringing, foreground & background calls. + * @param imsServiceTypes Array of IMS call service type for ringing, foreground & + * background calls. + * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls. */ public void notifyPreciseCallState(int slotIndex, int subId, - @PreciseCallStates int ringCallPreciseState, - @PreciseCallStates int foregroundCallPreciseState, - @PreciseCallStates int backgroundCallPreciseState) { + @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds, + @Annotation.ImsCallServiceType int[] imsServiceTypes, + @Annotation.ImsCallType int[] imsCallTypes) { try { - sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState, - foregroundCallPreciseState, backgroundCallPreciseState); + sRegistry.notifyPreciseCallState(slotIndex, subId, callStates, + imsCallIds, imsServiceTypes, imsCallTypes); } catch (RemoteException ex) { // system process is dead throw ex.rethrowFromSystemServer(); diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index 2a8e7e468616..080c0d81f95b 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -533,6 +533,13 @@ public final class PointerIcon implements Parcelable { mHotSpotY = hotSpotY; } + @Override + public String toString() { + return "PointerIcon{type=" + typeToString(mType) + + ", hotspotX=" + mHotSpotX + ", hotspotY=" + mHotSpotY + + ", systemIconResourceId=" + mSystemIconResourceId + "}"; + } + private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY) { if (hotSpotX < 0 || hotSpotX >= bitmap.getWidth()) { throw new IllegalArgumentException("x hotspot lies outside of the bitmap area"); @@ -624,4 +631,40 @@ public final class PointerIcon implements Parcelable { displayManager.registerDisplayListener(sDisplayListener, null /* handler */); } + /** + * Convert type constant to string. + * @hide + */ + public static String typeToString(int type) { + switch (type) { + case TYPE_CUSTOM: return "CUSTOM"; + case TYPE_NULL: return "NULL"; + case TYPE_NOT_SPECIFIED: return "NOT_SPECIFIED"; + case TYPE_ARROW: return "ARROW"; + case TYPE_SPOT_HOVER: return "SPOT_HOVER"; + case TYPE_SPOT_TOUCH: return "SPOT_TOUCH"; + case TYPE_SPOT_ANCHOR: return "SPOT_ANCHOR"; + case TYPE_CONTEXT_MENU: return "CONTEXT_MENU"; + case TYPE_HAND: return "HAND"; + case TYPE_HELP: return "HELP"; + case TYPE_WAIT: return "WAIT"; + case TYPE_CELL: return "CELL"; + case TYPE_CROSSHAIR: return "CROSSHAIR"; + case TYPE_TEXT: return "TEXT"; + case TYPE_VERTICAL_TEXT: return "VERTICAL_TEXT"; + case TYPE_ALIAS: return "ALIAS"; + case TYPE_COPY: return "COPY"; + case TYPE_NO_DROP: return "NO_DROP"; + case TYPE_ALL_SCROLL: return "ALL_SCROLL"; + case TYPE_HORIZONTAL_DOUBLE_ARROW: return "HORIZONTAL_DOUBLE_ARROW"; + case TYPE_VERTICAL_DOUBLE_ARROW: return "VERTICAL_DOUBLE_ARROW"; + case TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW: return "TOP_RIGHT_DIAGONAL_DOUBLE_ARROW"; + case TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW: return "TOP_LEFT_DIAGONAL_DOUBLE_ARROW"; + case TYPE_ZOOM_IN: return "ZOOM_IN"; + case TYPE_ZOOM_OUT: return "ZOOM_OUT"; + case TYPE_GRAB: return "GRAB"; + case TYPE_GRABBING: return "GRABBING"; + default: return Integer.toString(type); + } + } } diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index d77e499357b9..03b25c25ab99 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -29,6 +29,7 @@ import static android.view.WindowInsets.Type.STATUS_BARS; import static android.view.WindowInsets.Type.SYSTEM_GESTURES; import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT; import static android.view.WindowInsets.Type.all; +import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.indexOf; import static android.view.WindowInsets.Type.systemBars; @@ -597,7 +598,10 @@ public final class WindowInsets { return new WindowInsets(null, null, mTypeVisibilityMap, mIsRound, mAlwaysConsumeSystemBars, - displayCutoutCopyConstructorArgument(this), + // If the system window insets types contain displayCutout, we should also consume + // it. + (mCompatInsetsTypes & displayCutout()) != 0 + ? null : displayCutoutCopyConstructorArgument(this), mRoundedCorners, mPrivacyIndicatorBounds, mCompatInsetsTypes, mCompatIgnoreVisibility); } diff --git a/core/java/android/window/WindowProviderService.java b/core/java/android/window/WindowProviderService.java index fdc3e5af8d8b..f2ae973500af 100644 --- a/core/java/android/window/WindowProviderService.java +++ b/core/java/android/window/WindowProviderService.java @@ -146,7 +146,7 @@ public abstract class WindowProviderService extends Service implements WindowPro @SuppressLint("OnNameExpected") @Override - public void onConfigurationChanged(@Nullable Configuration configuration) { + public void onConfigurationChanged(@NonNull Configuration configuration) { // This is only called from WindowTokenClient. mCallbacksController.dispatchConfigurationChanged(configuration); } diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index fc526203beed..23167382ec3b 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -17,18 +17,15 @@ package com.android.internal.app; import android.annotation.IntDef; import android.annotation.Nullable; +import android.annotation.NonNull; +import android.annotation.UserIdInt; import android.app.AppGlobals; -import android.app.admin.DevicePolicyEventLogger; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; -import android.content.pm.ResolveInfo; -import android.os.AsyncTask; import android.os.Trace; import android.os.UserHandle; -import android.os.UserManager; -import android.stats.devicepolicy.DevicePolicyEnums; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -60,73 +57,31 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private final Context mContext; private int mCurrentPage; private OnProfileSelectedListener mOnProfileSelectedListener; - private OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener; private Set<Integer> mLoadedPages; - private final UserHandle mPersonalProfileUserHandle; + private final EmptyStateProvider mEmptyStateProvider; private final UserHandle mWorkProfileUserHandle; - private Injector mInjector; - private boolean mIsWaitingToEnableWorkProfile; + private final QuietModeManager mQuietModeManager; AbstractMultiProfilePagerAdapter(Context context, int currentPage, - UserHandle personalProfileUserHandle, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, UserHandle workProfileUserHandle) { mContext = Objects.requireNonNull(context); mCurrentPage = currentPage; mLoadedPages = new HashSet<>(); - mPersonalProfileUserHandle = personalProfileUserHandle; mWorkProfileUserHandle = workProfileUserHandle; - UserManager userManager = context.getSystemService(UserManager.class); - mInjector = new Injector() { - @Override - public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, - int targetUserId) { - return AbstractMultiProfilePagerAdapter.this - .hasCrossProfileIntents(intents, sourceUserId, targetUserId); - } - - @Override - public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { - return userManager.isQuietModeEnabled(workProfileUserHandle); - } - - @Override - public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) { - AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { - userManager.requestQuietModeEnabled(enabled, workProfileUserHandle); - }); - mIsWaitingToEnableWorkProfile = true; - } - }; - } - - protected void markWorkProfileEnabledBroadcastReceived() { - mIsWaitingToEnableWorkProfile = false; - } - - protected boolean isWaitingToEnableWorkProfile() { - return mIsWaitingToEnableWorkProfile; - } - - /** - * Overrides the default {@link Injector} for testing purposes. - */ - @VisibleForTesting - public void setInjector(Injector injector) { - mInjector = injector; + mEmptyStateProvider = emptyStateProvider; + mQuietModeManager = quietModeManager; } - protected boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { - return mInjector.isQuietModeEnabled(workProfileUserHandle); + private boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { + return mQuietModeManager.isQuietModeEnabled(workProfileUserHandle); } void setOnProfileSelectedListener(OnProfileSelectedListener listener) { mOnProfileSelectedListener = listener; } - void setOnSwitchOnWorkSelectedListener(OnSwitchOnWorkSelectedListener listener) { - mOnSwitchOnWorkSelectedListener = listener; - } - Context getContext() { return mContext; } @@ -280,8 +235,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { abstract @Nullable ViewGroup getInactiveAdapterView(); - abstract String getMetricsCategory(); - /** * Rebuilds the tab that is currently visible to the user. * <p>Returns {@code true} if rebuild has completed. @@ -317,41 +270,18 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { } private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) { - if (shouldShowNoCrossProfileIntentsEmptyState(activeListAdapter)) { + if (shouldSkipRebuild(activeListAdapter)) { activeListAdapter.postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true); return false; } return activeListAdapter.rebuildList(doPostProcessing); } - private boolean shouldShowNoCrossProfileIntentsEmptyState( - ResolverListAdapter activeListAdapter) { - UserHandle listUserHandle = activeListAdapter.getUserHandle(); - return UserHandle.myUserId() != listUserHandle.getIdentifier() - && allowShowNoCrossProfileIntentsEmptyState() - && !mInjector.hasCrossProfileIntents(activeListAdapter.getIntents(), - UserHandle.myUserId(), listUserHandle.getIdentifier()); - } - - boolean allowShowNoCrossProfileIntentsEmptyState() { - return true; + private boolean shouldSkipRebuild(ResolverListAdapter activeListAdapter) { + EmptyState emptyState = mEmptyStateProvider.getEmptyState(activeListAdapter); + return emptyState != null && emptyState.shouldSkipDataRebuild(); } - protected abstract void showWorkProfileOffEmptyState( - ResolverListAdapter activeListAdapter, View.OnClickListener listener); - - protected abstract void showNoPersonalToWorkIntentsEmptyState( - ResolverListAdapter activeListAdapter); - - protected abstract void showNoPersonalAppsAvailableEmptyState( - ResolverListAdapter activeListAdapter); - - protected abstract void showNoWorkAppsAvailableEmptyState( - ResolverListAdapter activeListAdapter); - - protected abstract void showNoWorkToPersonalIntentsEmptyState( - ResolverListAdapter activeListAdapter); - /** * The empty state screens are shown according to their priority: * <ol> @@ -366,103 +296,88 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { * anyway. */ void showEmptyResolverListEmptyState(ResolverListAdapter listAdapter) { - if (maybeShowNoCrossProfileIntentsEmptyState(listAdapter)) { + final EmptyState emptyState = mEmptyStateProvider.getEmptyState(listAdapter); + + if (emptyState == null) { return; } - if (maybeShowWorkProfileOffEmptyState(listAdapter)) { - return; + + emptyState.onEmptyStateShown(); + + View.OnClickListener clickListener = null; + + if (emptyState.getButtonClickListener() != null) { + clickListener = v -> emptyState.getButtonClickListener().onClick(() -> { + ProfileDescriptor descriptor = getItem( + userHandleToPageIndex(listAdapter.getUserHandle())); + AbstractMultiProfilePagerAdapter.this.showSpinner(descriptor.getEmptyStateView()); + }); } - maybeShowNoAppsAvailableEmptyState(listAdapter); + + showEmptyState(listAdapter, emptyState, clickListener); } - private boolean maybeShowNoCrossProfileIntentsEmptyState(ResolverListAdapter listAdapter) { - if (!shouldShowNoCrossProfileIntentsEmptyState(listAdapter)) { - return false; - } - if (listAdapter.getUserHandle().equals(mPersonalProfileUserHandle)) { - DevicePolicyEventLogger.createEvent( - DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL) - .setStrings(getMetricsCategory()) - .write(); - showNoWorkToPersonalIntentsEmptyState(listAdapter); - } else { - DevicePolicyEventLogger.createEvent( - DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK) - .setStrings(getMetricsCategory()) - .write(); - showNoPersonalToWorkIntentsEmptyState(listAdapter); + /** + * Class to get user id of the current process + */ + public static class MyUserIdProvider { + /** + * @return user id of the current process + */ + public int getMyUserId() { + return UserHandle.myUserId(); } - return true; } /** - * Returns {@code true} if the work profile off empty state screen is shown. + * Utility class to check if there are cross profile intents, it is in a separate class so + * it could be mocked in tests */ - private boolean maybeShowWorkProfileOffEmptyState(ResolverListAdapter listAdapter) { - UserHandle listUserHandle = listAdapter.getUserHandle(); - if (!listUserHandle.equals(mWorkProfileUserHandle) - || !mInjector.isQuietModeEnabled(mWorkProfileUserHandle) - || listAdapter.getCount() == 0) { - return false; - } - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums.RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED) - .setStrings(getMetricsCategory()) - .write(); - showWorkProfileOffEmptyState(listAdapter, - v -> { - ProfileDescriptor descriptor = getItem( - userHandleToPageIndex(listAdapter.getUserHandle())); - showSpinner(descriptor.getEmptyStateView()); - if (mOnSwitchOnWorkSelectedListener != null) { - mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected(); - } - mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle); - }); - return true; - } - - private void maybeShowNoAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - UserHandle listUserHandle = listAdapter.getUserHandle(); - if (mWorkProfileUserHandle != null - && (UserHandle.myUserId() == listUserHandle.getIdentifier() - || !hasAppsInOtherProfile(listAdapter))) { - DevicePolicyEventLogger.createEvent( - DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED) - .setStrings(getMetricsCategory()) - .setBoolean(/*isPersonalProfile*/ listUserHandle == mPersonalProfileUserHandle) - .write(); - if (listUserHandle == mPersonalProfileUserHandle) { - showNoPersonalAppsAvailableEmptyState(listAdapter); - } else { - showNoWorkAppsAvailableEmptyState(listAdapter); - } - } else if (mWorkProfileUserHandle == null) { - showConsumerUserNoAppsAvailableEmptyState(listAdapter); + public static class CrossProfileIntentsChecker { + + private final ContentResolver mContentResolver; + + public CrossProfileIntentsChecker(@NonNull ContentResolver contentResolver) { + mContentResolver = contentResolver; } - } - protected void showEmptyState(ResolverListAdapter activeListAdapter, String title, - String subtitle) { - showEmptyState(activeListAdapter, title, subtitle, /* buttonOnClick */ null); + /** + * Returns {@code true} if at least one of the provided {@code intents} can be forwarded + * from {@code source} (user id) to {@code target} (user id). + */ + public boolean hasCrossProfileIntents(List<Intent> intents, @UserIdInt int source, + @UserIdInt int target) { + IPackageManager packageManager = AppGlobals.getPackageManager(); + + return intents.stream().anyMatch(intent -> + null != IntentForwarderActivity.canForward(intent, source, target, + packageManager, mContentResolver)); + } } - protected void showEmptyState(ResolverListAdapter activeListAdapter, - String title, String subtitle, View.OnClickListener buttonOnClick) { + protected void showEmptyState(ResolverListAdapter activeListAdapter, EmptyState emptyState, + View.OnClickListener buttonOnClick) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); descriptor.rootView.findViewById(R.id.resolver_list).setVisibility(View.GONE); ViewGroup emptyStateView = descriptor.getEmptyStateView(); - resetViewVisibilitiesForWorkProfileEmptyState(emptyStateView); + resetViewVisibilitiesForEmptyState(emptyStateView); emptyStateView.setVisibility(View.VISIBLE); View container = emptyStateView.findViewById(R.id.resolver_empty_state_container); setupContainerPadding(container); TextView titleView = emptyStateView.findViewById(R.id.resolver_empty_state_title); - titleView.setText(title); + String title = emptyState.getTitle(); + if (title != null) { + titleView.setVisibility(View.VISIBLE); + titleView.setText(title); + } else { + titleView.setVisibility(View.GONE); + } TextView subtitleView = emptyStateView.findViewById(R.id.resolver_empty_state_subtitle); + String subtitle = emptyState.getSubtitle(); if (subtitle != null) { subtitleView.setVisibility(View.VISIBLE); subtitleView.setText(subtitle); @@ -470,6 +385,9 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { subtitleView.setVisibility(View.GONE); } + View defaultEmptyText = emptyStateView.findViewById(R.id.empty); + defaultEmptyText.setVisibility(emptyState.useDefaultEmptyView() ? View.VISIBLE : View.GONE); + Button button = emptyStateView.findViewById(R.id.resolver_empty_state_button); button.setVisibility(buttonOnClick != null ? View.VISIBLE : View.GONE); button.setOnClickListener(buttonOnClick); @@ -483,22 +401,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { */ protected void setupContainerPadding(View container) {} - private void showConsumerUserNoAppsAvailableEmptyState(ResolverListAdapter activeListAdapter) { - ProfileDescriptor descriptor = getItem( - userHandleToPageIndex(activeListAdapter.getUserHandle())); - descriptor.rootView.findViewById(R.id.resolver_list).setVisibility(View.GONE); - View emptyStateView = descriptor.getEmptyStateView(); - resetViewVisibilitiesForConsumerUserEmptyState(emptyStateView); - emptyStateView.setVisibility(View.VISIBLE); - - activeListAdapter.markTabLoaded(); - } - - private boolean isSpinnerShowing(View emptyStateView) { - return emptyStateView.findViewById(R.id.resolver_empty_state_progress).getVisibility() - == View.VISIBLE; - } - private void showSpinner(View emptyStateView) { emptyStateView.findViewById(R.id.resolver_empty_state_title).setVisibility(View.INVISIBLE); emptyStateView.findViewById(R.id.resolver_empty_state_button).setVisibility(View.INVISIBLE); @@ -506,7 +408,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { emptyStateView.findViewById(R.id.empty).setVisibility(View.GONE); } - private void resetViewVisibilitiesForWorkProfileEmptyState(View emptyStateView) { + private void resetViewVisibilitiesForEmptyState(View emptyStateView) { emptyStateView.findViewById(R.id.resolver_empty_state_title).setVisibility(View.VISIBLE); emptyStateView.findViewById(R.id.resolver_empty_state_subtitle).setVisibility(View.VISIBLE); emptyStateView.findViewById(R.id.resolver_empty_state_button).setVisibility(View.INVISIBLE); @@ -514,14 +416,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { emptyStateView.findViewById(R.id.empty).setVisibility(View.GONE); } - private void resetViewVisibilitiesForConsumerUserEmptyState(View emptyStateView) { - emptyStateView.findViewById(R.id.resolver_empty_state_title).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.resolver_empty_state_subtitle).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.resolver_empty_state_button).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.resolver_empty_state_progress).setVisibility(View.GONE); - emptyStateView.findViewById(R.id.empty).setVisibility(View.VISIBLE); - } - protected void showListView(ResolverListAdapter activeListAdapter) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); @@ -530,33 +424,6 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { emptyStateView.setVisibility(View.GONE); } - private boolean hasCrossProfileIntents(List<Intent> intents, int source, int target) { - IPackageManager packageManager = AppGlobals.getPackageManager(); - ContentResolver contentResolver = mContext.getContentResolver(); - for (Intent intent : intents) { - if (IntentForwarderActivity.canForward(intent, source, target, packageManager, - contentResolver) != null) { - return true; - } - } - return false; - } - - private boolean hasAppsInOtherProfile(ResolverListAdapter adapter) { - if (mWorkProfileUserHandle == null) { - return false; - } - List<ResolverActivity.ResolvedComponentInfo> resolversForIntent = - adapter.getResolversForUser(UserHandle.of(UserHandle.myUserId())); - for (ResolverActivity.ResolvedComponentInfo info : resolversForIntent) { - ResolveInfo resolveInfo = info.getResolveInfoAt(0); - if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) { - return true; - } - } - return false; - } - boolean shouldShowEmptyStateScreen(ResolverListAdapter listAdapter) { int count = listAdapter.getUnfilteredCount(); return (count == 0 && listAdapter.getPlaceholderCount() == 0) @@ -600,6 +467,98 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { } /** + * Returns an empty state to show for the current profile page (tab) if necessary. + * This could be used e.g. to show a blocker on a tab if device management policy doesn't + * allow to use it or there are no apps available. + */ + public interface EmptyStateProvider { + /** + * When a non-null empty state is returned the corresponding profile page will show + * this empty state + * @param resolverListAdapter the current adapter + */ + @Nullable + default EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + return null; + } + } + + /** + * Empty state provider that combines multiple providers. Providers earlier in the list have + * priority, that is if there is a provider that returns non-null empty state then all further + * providers will be ignored. + */ + public static class CompositeEmptyStateProvider implements EmptyStateProvider { + + private final EmptyStateProvider[] mProviders; + + public CompositeEmptyStateProvider(EmptyStateProvider... providers) { + mProviders = providers; + } + + @Nullable + @Override + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + for (EmptyStateProvider provider : mProviders) { + EmptyState emptyState = provider.getEmptyState(resolverListAdapter); + if (emptyState != null) { + return emptyState; + } + } + return null; + } + } + + /** + * Describes how the blocked empty state should look like for a profile tab + */ + public interface EmptyState { + /** + * Title that will be shown on the empty state + */ + @Nullable + default String getTitle() { return null; } + + /** + * Subtitle that will be shown underneath the title on the empty state + */ + @Nullable + default String getSubtitle() { return null; } + + /** + * If non-null then a button will be shown and this listener will be called + * when the button is clicked + */ + @Nullable + default ClickListener getButtonClickListener() { return null; } + + /** + * If true then default text ('No apps can perform this action') and style for the empty + * state will be applied, title and subtitle will be ignored. + */ + default boolean useDefaultEmptyView() { return false; } + + /** + * Returns true if for this empty state we should skip rebuilding of the apps list + * for this tab. + */ + default boolean shouldSkipDataRebuild() { return false; } + + /** + * Called when empty state is shown, could be used e.g. to track analytics events + */ + default void onEmptyStateShown() {} + + interface ClickListener { + void onClick(TabControl currentTab); + } + + interface TabControl { + void showSpinner(); + } + } + + /** * Listener for when the user switches on the work profile from the work tab. */ interface OnSwitchOnWorkSelectedListener { @@ -612,14 +571,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { /** * Describes an injector to be used for cross profile functionality. Overridable for testing. */ - @VisibleForTesting - public interface Injector { - /** - * Returns {@code true} if at least one of the provided {@code intents} can be forwarded - * from {@code sourceUserId} to {@code targetUserId}. - */ - boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, int targetUserId); - + public interface QuietModeManager { /** * Returns whether the given profile is in quiet mode or not. */ @@ -629,5 +581,15 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { * Enables or disables quiet mode for a managed profile. */ void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle); + + /** + * Should be called when the work profile enabled broadcast received + */ + void markWorkProfileEnabledBroadcastReceived(); + + /** + * Returns true if enabling of work profile is in progress + */ + boolean isWaitingToEnableWorkProfile(); } }
\ No newline at end of file diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index d37779bfe588..02cbd4101903 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -16,6 +16,14 @@ package com.android.internal.app; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; +import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL; +import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK; + import static com.android.internal.util.LatencyTracker.ACTION_LOAD_SHARE_SHEET; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -114,6 +122,9 @@ import android.widget.TextView; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.NoCrossProfileEmptyStateProvider.DevicePolicyBlockerEmptyState; import com.android.internal.app.ResolverListAdapter.ActivityInfoPresentationGetter; import com.android.internal.app.ResolverListAdapter.ViewHolder; import com.android.internal.app.chooser.ChooserTargetInfo; @@ -830,6 +841,41 @@ public class ChooserActivity extends ResolverActivity implements return mChooserMultiProfilePagerAdapter; } + @Override + protected EmptyStateProvider createBlockerEmptyStateProvider() { + final boolean isSendAction = isSendAction(getTargetIntent()); + + final EmptyState noWorkToPersonalEmptyState = + new DevicePolicyBlockerEmptyState( + /* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ + isSendAction ? RESOLVER_CANT_SHARE_WITH_PERSONAL : RESOLVER_CANT_ACCESS_PERSONAL, + /* defaultSubtitleResource= */ + isSendAction ? R.string.resolver_cant_share_with_personal_apps_explanation + : R.string.resolver_cant_access_personal_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_CHOOSER); + + final EmptyState noPersonalToWorkEmptyState = + new DevicePolicyBlockerEmptyState( + /* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ + isSendAction ? RESOLVER_CANT_SHARE_WITH_WORK : RESOLVER_CANT_ACCESS_WORK, + /* defaultSubtitleResource= */ + isSendAction ? R.string.resolver_cant_share_with_work_apps_explanation + : R.string.resolver_cant_access_work_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_CHOOSER); + + return new NoCrossProfileEmptyStateProvider(getPersonalProfileUserHandle(), + noWorkToPersonalEmptyState, noPersonalToWorkEmptyState, + createCrossProfileIntentsChecker(), createMyUserIdProvider()); + } + private ChooserMultiProfilePagerAdapter createChooserMultiProfilePagerAdapterForOneProfile( Intent[] initialIntents, List<ResolveInfo> rList, @@ -844,9 +890,10 @@ public class ChooserActivity extends ResolverActivity implements return new ChooserMultiProfilePagerAdapter( /* context */ this, adapter, - getPersonalProfileUserHandle(), + createEmptyStateProvider(/* workProfileUserHandle= */ null), + mQuietModeManager, /* workProfileUserHandle= */ null, - isSendAction(getTargetIntent()), mMaxTargetsPerRow); + mMaxTargetsPerRow); } private ChooserMultiProfilePagerAdapter createChooserMultiProfilePagerAdapterForTwoProfiles( @@ -872,10 +919,11 @@ public class ChooserActivity extends ResolverActivity implements /* context */ this, personalAdapter, workAdapter, + createEmptyStateProvider(/* workProfileUserHandle= */ getWorkProfileUserHandle()), + mQuietModeManager, selectedProfile, - getPersonalProfileUserHandle(), getWorkProfileUserHandle(), - isSendAction(getTargetIntent()), mMaxTargetsPerRow); + mMaxTargetsPerRow); } private int findSelectedProfile() { diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java index df1130be5ec6..0509b6754218 100644 --- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java @@ -16,17 +16,7 @@ package com.android.internal.app; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_PERSONAL_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_WORK_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PAUSED_TITLE; - import android.annotation.Nullable; -import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.UserHandle; import android.view.LayoutInflater; @@ -47,37 +37,37 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd private static final int SINGLE_CELL_SPAN_SIZE = 1; private final ChooserProfileDescriptor[] mItems; - private final boolean mIsSendAction; private int mBottomOffset; private int mMaxTargetsPerRow; ChooserMultiProfilePagerAdapter(Context context, ChooserActivity.ChooserGridAdapter adapter, - UserHandle personalProfileUserHandle, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, UserHandle workProfileUserHandle, - boolean isSendAction, int maxTargetsPerRow) { - super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle); + int maxTargetsPerRow) { + super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager, + workProfileUserHandle); mItems = new ChooserProfileDescriptor[] { createProfileDescriptor(adapter) }; - mIsSendAction = isSendAction; mMaxTargetsPerRow = maxTargetsPerRow; } ChooserMultiProfilePagerAdapter(Context context, ChooserActivity.ChooserGridAdapter personalAdapter, ChooserActivity.ChooserGridAdapter workAdapter, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, @Profile int defaultProfile, - UserHandle personalProfileUserHandle, UserHandle workProfileUserHandle, - boolean isSendAction, int maxTargetsPerRow) { - super(context, /* currentPage */ defaultProfile, personalProfileUserHandle, - workProfileUserHandle); + int maxTargetsPerRow) { + super(context, /* currentPage */ defaultProfile, emptyStateProvider, + quietModeManager, workProfileUserHandle); mItems = new ChooserProfileDescriptor[] { createProfileDescriptor(personalAdapter), createProfileDescriptor(workAdapter) }; - mIsSendAction = isSendAction; mMaxTargetsPerRow = maxTargetsPerRow; } @@ -192,112 +182,6 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd return getListViewForIndex(1 - getCurrentPage()); } - @Override - String getMetricsCategory() { - return ResolverActivity.METRICS_CATEGORY_CHOOSER; - } - - @Override - protected void showWorkProfileOffEmptyState(ResolverListAdapter activeListAdapter, - View.OnClickListener listener) { - showEmptyState(activeListAdapter, - getWorkAppPausedTitle(), - /* subtitle = */ null, - listener); - } - - @Override - protected void showNoPersonalToWorkIntentsEmptyState(ResolverListAdapter activeListAdapter) { - if (mIsSendAction) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantShareWithWorkMessage()); - } else { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessWorkMessage()); - } - } - - @Override - protected void showNoWorkToPersonalIntentsEmptyState(ResolverListAdapter activeListAdapter) { - if (mIsSendAction) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantShareWithPersonalMessage()); - } else { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessPersonalMessage()); - } - } - - @Override - protected void showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, getNoPersonalAppsAvailableMessage(), /* subtitle= */ null); - - } - - @Override - protected void showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, getNoWorkAppsAvailableMessage(), /* subtitle = */ null); - } - - private String getWorkAppPausedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_WORK_PAUSED_TITLE, - () -> getContext().getString(R.string.resolver_turn_on_work_apps)); - } - - private String getCrossProfileBlockedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, - () -> getContext().getString(R.string.resolver_cross_profile_blocked)); - } - - private String getCantShareWithWorkMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_SHARE_WITH_WORK, - () -> getContext().getString( - R.string.resolver_cant_share_with_work_apps_explanation)); - } - - private String getCantShareWithPersonalMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_SHARE_WITH_PERSONAL, - () -> getContext().getString( - R.string.resolver_cant_share_with_personal_apps_explanation)); - } - - private String getCantAccessWorkMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_WORK, - () -> getContext().getString( - R.string.resolver_cant_access_work_apps_explanation)); - } - - private String getCantAccessPersonalMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_PERSONAL, - () -> getContext().getString( - R.string.resolver_cant_access_personal_apps_explanation)); - } - - private String getNoWorkAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_WORK_APPS, - () -> getContext().getString( - R.string.resolver_no_work_apps_available)); - } - - private String getNoPersonalAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_PERSONAL_APPS, - () -> getContext().getString( - R.string.resolver_no_personal_apps_available)); - } - - void setEmptyStateBottomOffset(int bottomOffset) { mBottomOffset = bottomOffset; } diff --git a/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java b/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java new file mode 100644 index 000000000000..34249f2457c7 --- /dev/null +++ b/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_PERSONAL_APPS; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_WORK_APPS; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.admin.DevicePolicyEventLogger; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.content.pm.ResolveInfo; +import android.os.UserHandle; +import android.stats.devicepolicy.nano.DevicePolicyEnums; + +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.R; + +import java.util.List; + +/** + * Chooser/ResolverActivity empty state provider that returns empty state which is shown when + * there are no apps available. + */ +public class NoAppsAvailableEmptyStateProvider implements EmptyStateProvider { + + @NonNull + private final Context mContext; + @Nullable + private final UserHandle mWorkProfileUserHandle; + @Nullable + private final UserHandle mPersonalProfileUserHandle; + @NonNull + private final String mMetricsCategory; + @NonNull + private final MyUserIdProvider mMyUserIdProvider; + + public NoAppsAvailableEmptyStateProvider(Context context, UserHandle workProfileUserHandle, + UserHandle personalProfileUserHandle, String metricsCategory, + MyUserIdProvider myUserIdProvider) { + mContext = context; + mWorkProfileUserHandle = workProfileUserHandle; + mPersonalProfileUserHandle = personalProfileUserHandle; + mMetricsCategory = metricsCategory; + mMyUserIdProvider = myUserIdProvider; + } + + @Nullable + @Override + @SuppressWarnings("ReferenceEquality") + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + UserHandle listUserHandle = resolverListAdapter.getUserHandle(); + + if (mWorkProfileUserHandle != null + && (mMyUserIdProvider.getMyUserId() == listUserHandle.getIdentifier() + || !hasAppsInOtherProfile(resolverListAdapter))) { + + String title; + if (listUserHandle == mPersonalProfileUserHandle) { + title = mContext.getSystemService( + DevicePolicyManager.class).getResources().getString( + RESOLVER_NO_PERSONAL_APPS, + () -> mContext.getString(R.string.resolver_no_personal_apps_available)); + } else { + title = mContext.getSystemService( + DevicePolicyManager.class).getResources().getString( + RESOLVER_NO_WORK_APPS, + () -> mContext.getString(R.string.resolver_no_work_apps_available)); + } + + return new NoAppsAvailableEmptyState( + title, mMetricsCategory, + /* isPersonalProfile= */ listUserHandle == mPersonalProfileUserHandle + ); + } else if (mWorkProfileUserHandle == null) { + // Return default empty state without tracking + return new DefaultEmptyState(); + } + + return null; + } + + private boolean hasAppsInOtherProfile(ResolverListAdapter adapter) { + if (mWorkProfileUserHandle == null) { + return false; + } + List<ResolverActivity.ResolvedComponentInfo> resolversForIntent = + adapter.getResolversForUser(UserHandle.of(mMyUserIdProvider.getMyUserId())); + for (ResolverActivity.ResolvedComponentInfo info : resolversForIntent) { + ResolveInfo resolveInfo = info.getResolveInfoAt(0); + if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) { + return true; + } + } + return false; + } + + public static class DefaultEmptyState implements EmptyState { + @Override + public boolean useDefaultEmptyView() { + return true; + } + } + + public static class NoAppsAvailableEmptyState implements EmptyState { + + @NonNull + private String mTitle; + + @NonNull + private String mMetricsCategory; + + private boolean mIsPersonalProfile; + + public NoAppsAvailableEmptyState(String title, String metricsCategory, + boolean isPersonalProfile) { + mTitle = title; + mMetricsCategory = metricsCategory; + mIsPersonalProfile = isPersonalProfile; + } + + @Nullable + @Override + public String getTitle() { + return mTitle; + } + + @Override + public void onEmptyStateShown() { + DevicePolicyEventLogger.createEvent( + DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED) + .setStrings(mMetricsCategory) + .setBoolean(/*isPersonalProfile*/ mIsPersonalProfile) + .write(); + } + } +}
\ No newline at end of file diff --git a/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java b/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java new file mode 100644 index 000000000000..2e7d5bf00e27 --- /dev/null +++ b/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.StringRes; +import android.app.admin.DevicePolicyEventLogger; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.UserHandle; + +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; + +/** + * Empty state provider that does not allow cross profile sharing, it will return a blocker + * in case if the profile of the current tab is not the same as the profile of the calling app. + */ +public class NoCrossProfileEmptyStateProvider implements EmptyStateProvider { + + private final UserHandle mPersonalProfileUserHandle; + private final EmptyState mNoWorkToPersonalEmptyState; + private final EmptyState mNoPersonalToWorkEmptyState; + private final CrossProfileIntentsChecker mCrossProfileIntentsChecker; + private final MyUserIdProvider mUserIdProvider; + + public NoCrossProfileEmptyStateProvider(UserHandle personalUserHandle, + EmptyState noWorkToPersonalEmptyState, + EmptyState noPersonalToWorkEmptyState, + CrossProfileIntentsChecker crossProfileIntentsChecker, + MyUserIdProvider myUserIdProvider) { + mPersonalProfileUserHandle = personalUserHandle; + mNoWorkToPersonalEmptyState = noWorkToPersonalEmptyState; + mNoPersonalToWorkEmptyState = noPersonalToWorkEmptyState; + mCrossProfileIntentsChecker = crossProfileIntentsChecker; + mUserIdProvider = myUserIdProvider; + } + + @Nullable + @Override + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + boolean shouldShowBlocker = + mUserIdProvider.getMyUserId() != resolverListAdapter.getUserHandle().getIdentifier() + && !mCrossProfileIntentsChecker + .hasCrossProfileIntents(resolverListAdapter.getIntents(), + mUserIdProvider.getMyUserId(), + resolverListAdapter.getUserHandle().getIdentifier()); + + if (!shouldShowBlocker) { + return null; + } + + if (resolverListAdapter.getUserHandle().equals(mPersonalProfileUserHandle)) { + return mNoWorkToPersonalEmptyState; + } else { + return mNoPersonalToWorkEmptyState; + } + } + + + /** + * Empty state that gets strings from the device policy manager and tracks events into + * event logger of the device policy events. + */ + public static class DevicePolicyBlockerEmptyState implements EmptyState { + + @NonNull + private final Context mContext; + private final String mDevicePolicyStringTitleId; + @StringRes + private final int mDefaultTitleResource; + private final String mDevicePolicyStringSubtitleId; + @StringRes + private final int mDefaultSubtitleResource; + private final int mEventId; + @NonNull + private final String mEventCategory; + + public DevicePolicyBlockerEmptyState(Context context, String devicePolicyStringTitleId, + @StringRes int defaultTitleResource, String devicePolicyStringSubtitleId, + @StringRes int defaultSubtitleResource, + int devicePolicyEventId, String devicePolicyEventCategory) { + mContext = context; + mDevicePolicyStringTitleId = devicePolicyStringTitleId; + mDefaultTitleResource = defaultTitleResource; + mDevicePolicyStringSubtitleId = devicePolicyStringSubtitleId; + mDefaultSubtitleResource = defaultSubtitleResource; + mEventId = devicePolicyEventId; + mEventCategory = devicePolicyEventCategory; + } + + @Nullable + @Override + public String getTitle() { + return mContext.getSystemService(DevicePolicyManager.class).getResources().getString( + mDevicePolicyStringTitleId, + () -> mContext.getString(mDefaultTitleResource)); + } + + @Nullable + @Override + public String getSubtitle() { + return mContext.getSystemService(DevicePolicyManager.class).getResources().getString( + mDevicePolicyStringSubtitleId, + () -> mContext.getString(mDefaultSubtitleResource)); + } + + @Override + public void onEmptyStateShown() { + DevicePolicyEventLogger.createEvent(mEventId) + .setStrings(mEventCategory) + .write(); + } + + @Override + public boolean shouldSkipDataRebuild() { + return true; + } + } +} diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index a237e986f1d7..0706ee52ec3a 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -19,6 +19,9 @@ package com.android.internal.app; import static android.Manifest.permission.INTERACT_ACROSS_PROFILES; import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_PERSONAL; import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_PERSONAL_TAB; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_PERSONAL_TAB_ACCESSIBILITY; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PROFILE_NOT_SUPPORTED; @@ -26,6 +29,8 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_TAB_ACCESSIBILITY; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.PermissionChecker.PID_UNKNOWN; +import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL; +import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import android.annotation.Nullable; @@ -57,6 +62,7 @@ import android.content.res.TypedArray; import android.graphics.Insets; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.PatternMatcher; @@ -93,7 +99,14 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CompositeEmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.OnSwitchOnWorkSelectedListener; import com.android.internal.app.AbstractMultiProfilePagerAdapter.Profile; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; +import com.android.internal.app.NoCrossProfileEmptyStateProvider.DevicePolicyBlockerEmptyState; import com.android.internal.app.chooser.ChooserTargetInfo; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; @@ -186,6 +199,8 @@ public class ResolverActivity extends Activity implements @VisibleForTesting protected AbstractMultiProfilePagerAdapter mMultiProfilePagerAdapter; + protected QuietModeManager mQuietModeManager; + // Intent extra for connected audio devices public static final String EXTRA_IS_AUDIO_CAPTURE_DEVICE = "is_audio_capture_device"; @@ -217,6 +232,9 @@ public class ResolverActivity extends Activity implements private UserHandle mWorkProfileUserHandle; + @Nullable + private OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener; + protected final LatencyTracker mLatencyTracker = getLatencyTracker(); private LatencyTracker getLatencyTracker() { @@ -375,6 +393,8 @@ public class ResolverActivity extends Activity implements setTheme(appliedThemeResId()); super.onCreate(savedInstanceState); + mQuietModeManager = createQuietModeManager(); + // Determine whether we should show that intent is forwarded // from managed profile to owner or other way around. setProfileSwitchMessage(intent.getContentUserHint()); @@ -475,6 +495,111 @@ public class ResolverActivity extends Activity implements return resolverMultiProfilePagerAdapter; } + @VisibleForTesting + protected MyUserIdProvider createMyUserIdProvider() { + return new MyUserIdProvider(); + } + + @VisibleForTesting + protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { + return new CrossProfileIntentsChecker(getContentResolver()); + } + + @VisibleForTesting + protected QuietModeManager createQuietModeManager() { + UserManager userManager = getSystemService(UserManager.class); + return new QuietModeManager() { + + private boolean mIsWaitingToEnableWorkProfile = false; + + @Override + public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { + return userManager.isQuietModeEnabled(workProfileUserHandle); + } + + @Override + public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) { + AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { + userManager.requestQuietModeEnabled(enabled, workProfileUserHandle); + }); + mIsWaitingToEnableWorkProfile = true; + } + + @Override + public void markWorkProfileEnabledBroadcastReceived() { + mIsWaitingToEnableWorkProfile = false; + } + + @Override + public boolean isWaitingToEnableWorkProfile() { + return mIsWaitingToEnableWorkProfile; + } + }; + } + + protected EmptyStateProvider createBlockerEmptyStateProvider() { + final boolean shouldShowNoCrossProfileIntentsEmptyState = getUser().equals(getIntentUser()); + + if (!shouldShowNoCrossProfileIntentsEmptyState) { + // Implementation that doesn't show any blockers + return new EmptyStateProvider() {}; + } + + final AbstractMultiProfilePagerAdapter.EmptyState + noWorkToPersonalEmptyState = + new DevicePolicyBlockerEmptyState(/* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ RESOLVER_CANT_ACCESS_PERSONAL, + /* defaultSubtitleResource= */ + R.string.resolver_cant_access_personal_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_RESOLVER); + + final AbstractMultiProfilePagerAdapter.EmptyState noPersonalToWorkEmptyState = + new DevicePolicyBlockerEmptyState(/* context= */ this, + /* devicePolicyStringTitleId= */ RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, + /* defaultTitleResource= */ R.string.resolver_cross_profile_blocked, + /* devicePolicyStringSubtitleId= */ RESOLVER_CANT_ACCESS_WORK, + /* defaultSubtitleResource= */ + R.string.resolver_cant_access_work_apps_explanation, + /* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK, + /* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_RESOLVER); + + return new NoCrossProfileEmptyStateProvider(getPersonalProfileUserHandle(), + noWorkToPersonalEmptyState, noPersonalToWorkEmptyState, + createCrossProfileIntentsChecker(), createMyUserIdProvider()); + } + + protected EmptyStateProvider createEmptyStateProvider( + @Nullable UserHandle workProfileUserHandle) { + final EmptyStateProvider blockerEmptyStateProvider = createBlockerEmptyStateProvider(); + + final EmptyStateProvider workProfileOffEmptyStateProvider = + new WorkProfilePausedEmptyStateProvider(this, workProfileUserHandle, + mQuietModeManager, + /* onSwitchOnWorkSelectedListener= */ + () -> { if (mOnSwitchOnWorkSelectedListener != null) { + mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected(); + }}, + getMetricsCategory()); + + final EmptyStateProvider noAppsEmptyStateProvider = new NoAppsAvailableEmptyStateProvider( + this, + workProfileUserHandle, + getPersonalProfileUserHandle(), + getMetricsCategory(), + createMyUserIdProvider() + ); + + // Return composite provider, the order matters (the higher, the more priority) + return new CompositeEmptyStateProvider( + blockerEmptyStateProvider, + workProfileOffEmptyStateProvider, + noAppsEmptyStateProvider + ); + } + private ResolverMultiProfilePagerAdapter createResolverMultiProfilePagerAdapterForOneProfile( Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { @@ -485,10 +610,12 @@ public class ResolverActivity extends Activity implements rList, filterLastUsed, /* userHandle */ UserHandle.of(UserHandle.myUserId())); + QuietModeManager quietModeManager = createQuietModeManager(); return new ResolverMultiProfilePagerAdapter( /* context */ this, adapter, - getPersonalProfileUserHandle(), + createEmptyStateProvider(/* workProfileUserHandle= */ null), + quietModeManager, /* workProfileUserHandle= */ null); } @@ -539,14 +666,15 @@ public class ResolverActivity extends Activity implements (filterLastUsed && UserHandle.myUserId() == workProfileUserHandle.getIdentifier()), /* userHandle */ workProfileUserHandle); + QuietModeManager quietModeManager = createQuietModeManager(); return new ResolverMultiProfilePagerAdapter( /* context */ this, personalAdapter, workAdapter, + createEmptyStateProvider(getWorkProfileUserHandle()), + quietModeManager, selectedProfile, - getPersonalProfileUserHandle(), - getWorkProfileUserHandle(), - /* shouldShowNoCrossProfileIntentsEmptyState= */ getUser().equals(intentUser)); + getWorkProfileUserHandle()); } protected int appliedThemeResId() { @@ -853,9 +981,9 @@ public class ResolverActivity extends Activity implements } mRegistered = true; } - if (shouldShowTabs() && mMultiProfilePagerAdapter.isWaitingToEnableWorkProfile()) { - if (mMultiProfilePagerAdapter.isQuietModeEnabled(getWorkProfileUserHandle())) { - mMultiProfilePagerAdapter.markWorkProfileEnabledBroadcastReceived(); + if (shouldShowTabs() && mQuietModeManager.isWaitingToEnableWorkProfile()) { + if (mQuietModeManager.isQuietModeEnabled(getWorkProfileUserHandle())) { + mQuietModeManager.markWorkProfileEnabledBroadcastReceived(); } } mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); @@ -1815,13 +1943,12 @@ public class ResolverActivity extends Activity implements onHorizontalSwipeStateChanged(state); } }); - mMultiProfilePagerAdapter.setOnSwitchOnWorkSelectedListener( - () -> { - final View workTab = tabHost.getTabWidget().getChildAt(1); - workTab.setFocusable(true); - workTab.setFocusableInTouchMode(true); - workTab.requestFocus(); - }); + mOnSwitchOnWorkSelectedListener = () -> { + final View workTab = tabHost.getTabWidget().getChildAt(1); + workTab.setFocusable(true); + workTab.setFocusableInTouchMode(true); + workTab.requestFocus(); + }; } private String getPersonalTabLabel() { @@ -2082,7 +2209,7 @@ public class ResolverActivity extends Activity implements public void onHandlePackagesChanged(ResolverListAdapter listAdapter) { if (listAdapter == mMultiProfilePagerAdapter.getActiveListAdapter()) { if (listAdapter.getUserHandle().equals(getWorkProfileUserHandle()) - && mMultiProfilePagerAdapter.isWaitingToEnableWorkProfile()) { + && mQuietModeManager.isWaitingToEnableWorkProfile()) { // We have just turned on the work profile and entered the pass code to start it, // now we are waiting to receive the ACTION_USER_UNLOCKED broadcast. There is no // point in reloading the list now, since the work profile user is still @@ -2134,7 +2261,7 @@ public class ResolverActivity extends Activity implements } mWorkProfileHasBeenEnabled = true; - mMultiProfilePagerAdapter.markWorkProfileEnabledBroadcastReceived(); + mQuietModeManager.markWorkProfileEnabledBroadcastReceived(); } else { // Must be an UNAVAILABLE broadcast, so we watch for the next availability mWorkProfileHasBeenEnabled = false; @@ -2150,7 +2277,6 @@ public class ResolverActivity extends Activity implements }; } - @VisibleForTesting public static final class ResolvedComponentInfo { public final ComponentName name; private final List<Intent> mIntents = new ArrayList<>(); diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java index 0b33501fd875..9922051c1b0b 100644 --- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java @@ -16,15 +16,7 @@ package com.android.internal.app; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_PERSONAL; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_ACCESS_WORK; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_PERSONAL_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_NO_WORK_APPS; -import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PAUSED_TITLE; - import android.annotation.Nullable; -import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.UserHandle; import android.view.LayoutInflater; @@ -43,34 +35,33 @@ import com.android.internal.widget.PagerAdapter; public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerAdapter { private final ResolverProfileDescriptor[] mItems; - private final boolean mShouldShowNoCrossProfileIntentsEmptyState; private boolean mUseLayoutWithDefault; ResolverMultiProfilePagerAdapter(Context context, ResolverListAdapter adapter, - UserHandle personalProfileUserHandle, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, UserHandle workProfileUserHandle) { - super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle); + super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager, + workProfileUserHandle); mItems = new ResolverProfileDescriptor[] { createProfileDescriptor(adapter) }; - mShouldShowNoCrossProfileIntentsEmptyState = true; } ResolverMultiProfilePagerAdapter(Context context, ResolverListAdapter personalAdapter, ResolverListAdapter workAdapter, + EmptyStateProvider emptyStateProvider, + QuietModeManager quietModeManager, @Profile int defaultProfile, - UserHandle personalProfileUserHandle, - UserHandle workProfileUserHandle, - boolean shouldShowNoCrossProfileIntentsEmptyState) { - super(context, /* currentPage */ defaultProfile, personalProfileUserHandle, + UserHandle workProfileUserHandle) { + super(context, /* currentPage */ defaultProfile, emptyStateProvider, quietModeManager, workProfileUserHandle); mItems = new ResolverProfileDescriptor[] { createProfileDescriptor(personalAdapter), createProfileDescriptor(workAdapter) }; - mShouldShowNoCrossProfileIntentsEmptyState = shouldShowNoCrossProfileIntentsEmptyState; } private ResolverProfileDescriptor createProfileDescriptor( @@ -170,93 +161,6 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA return getListViewForIndex(1 - getCurrentPage()); } - @Override - String getMetricsCategory() { - return ResolverActivity.METRICS_CATEGORY_RESOLVER; - } - - @Override - boolean allowShowNoCrossProfileIntentsEmptyState() { - return mShouldShowNoCrossProfileIntentsEmptyState; - } - - @Override - protected void showWorkProfileOffEmptyState(ResolverListAdapter activeListAdapter, - View.OnClickListener listener) { - showEmptyState(activeListAdapter, - getWorkAppPausedTitle(), - /* subtitle = */ null, - listener); - } - - @Override - protected void showNoPersonalToWorkIntentsEmptyState(ResolverListAdapter activeListAdapter) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessWorkMessage()); - } - - @Override - protected void showNoWorkToPersonalIntentsEmptyState(ResolverListAdapter activeListAdapter) { - showEmptyState(activeListAdapter, - getCrossProfileBlockedTitle(), - getCantAccessPersonalMessage()); - } - - @Override - protected void showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, - getNoPersonalAppsAvailableMessage(), - /* subtitle = */ null); - } - - @Override - protected void showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter) { - showEmptyState(listAdapter, - getNoWorkAppsAvailableMessage(), - /* subtitle= */ null); - } - - private String getWorkAppPausedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_WORK_PAUSED_TITLE, - () -> getContext().getString(R.string.resolver_turn_on_work_apps)); - } - - private String getCrossProfileBlockedTitle() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CROSS_PROFILE_BLOCKED_TITLE, - () -> getContext().getString(R.string.resolver_cross_profile_blocked)); - } - - private String getCantAccessWorkMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_WORK, - () -> getContext().getString( - R.string.resolver_cant_access_work_apps_explanation)); - } - - private String getCantAccessPersonalMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_CANT_ACCESS_PERSONAL, - () -> getContext().getString( - R.string.resolver_cant_access_personal_apps_explanation)); - } - - private String getNoWorkAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_WORK_APPS, - () -> getContext().getString( - R.string.resolver_no_work_apps_available)); - } - - private String getNoPersonalAppsAvailableMessage() { - return getContext().getSystemService(DevicePolicyManager.class).getResources().getString( - RESOLVER_NO_PERSONAL_APPS, - () -> getContext().getString( - R.string.resolver_no_personal_apps_available)); - } - void setUseLayoutWithDefault(boolean useLayoutWithDefault) { mUseLayoutWithDefault = useLayoutWithDefault; } diff --git a/core/java/com/android/internal/app/WorkProfilePausedEmptyStateProvider.java b/core/java/com/android/internal/app/WorkProfilePausedEmptyStateProvider.java new file mode 100644 index 000000000000..6a88557663b1 --- /dev/null +++ b/core/java/com/android/internal/app/WorkProfilePausedEmptyStateProvider.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_PAUSED_TITLE; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.admin.DevicePolicyEventLogger; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.UserHandle; +import android.stats.devicepolicy.nano.DevicePolicyEnums; + +import com.android.internal.R; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.OnSwitchOnWorkSelectedListener; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; + +/** + * Chooser/ResolverActivity empty state provider that returns empty state which is shown when + * work profile is paused and we need to show a button to enable it. + */ +public class WorkProfilePausedEmptyStateProvider implements EmptyStateProvider { + + private final UserHandle mWorkProfileUserHandle; + private final QuietModeManager mQuietModeManager; + private final String mMetricsCategory; + private final OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener; + private final Context mContext; + + public WorkProfilePausedEmptyStateProvider(@NonNull Context context, + @Nullable UserHandle workProfileUserHandle, + @NonNull QuietModeManager quietModeManager, + @Nullable OnSwitchOnWorkSelectedListener onSwitchOnWorkSelectedListener, + @NonNull String metricsCategory) { + mContext = context; + mWorkProfileUserHandle = workProfileUserHandle; + mQuietModeManager = quietModeManager; + mMetricsCategory = metricsCategory; + mOnSwitchOnWorkSelectedListener = onSwitchOnWorkSelectedListener; + } + + @Nullable + @Override + public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) { + if (!resolverListAdapter.getUserHandle().equals(mWorkProfileUserHandle) + || !mQuietModeManager.isQuietModeEnabled(mWorkProfileUserHandle) + || resolverListAdapter.getCount() == 0) { + return null; + } + + final String title = mContext.getSystemService(DevicePolicyManager.class) + .getResources().getString(RESOLVER_WORK_PAUSED_TITLE, + () -> mContext.getString(R.string.resolver_turn_on_work_apps)); + + return new WorkProfileOffEmptyState(title, (tab) -> { + tab.showSpinner(); + if (mOnSwitchOnWorkSelectedListener != null) { + mOnSwitchOnWorkSelectedListener.onSwitchOnWorkSelected(); + } + mQuietModeManager.requestQuietModeEnabled(false, mWorkProfileUserHandle); + }, mMetricsCategory); + } + + public static class WorkProfileOffEmptyState implements EmptyState { + + private final String mTitle; + private final ClickListener mOnClick; + private final String mMetricsCategory; + + public WorkProfileOffEmptyState(String title, @NonNull ClickListener onClick, + @NonNull String metricsCategory) { + mTitle = title; + mOnClick = onClick; + mMetricsCategory = metricsCategory; + } + + @Nullable + @Override + public String getTitle() { + return mTitle; + } + + @Nullable + @Override + public ClickListener getButtonClickListener() { + return mOnClick; + } + + @Override + public void onEmptyStateShown() { + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED) + .setStrings(mMetricsCategory) + .write(); + } + } +} diff --git a/core/java/com/android/internal/content/om/OverlayManagerImpl.java b/core/java/com/android/internal/content/om/OverlayManagerImpl.java new file mode 100644 index 000000000000..76e068d11d74 --- /dev/null +++ b/core/java/com/android/internal/content/om/OverlayManagerImpl.java @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.content.om; + +import static android.content.Context.MODE_PRIVATE; + +import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; +import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; +import static com.android.internal.content.om.OverlayConfig.DEFAULT_PRIORITY; + +import android.annotation.NonNull; +import android.content.Context; +import android.content.om.OverlayInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.parsing.FrameworkParsingPackageUtils; +import android.os.FabricatedOverlayInfo; +import android.os.FabricatedOverlayInternal; +import android.os.FabricatedOverlayInternalEntry; +import android.os.FileUtils; +import android.os.Process; +import android.os.UserHandle; +import android.text.TextUtils; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.Preconditions; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * This class provides the functionalities of registering an overlay, unregistering an overlay, and + * getting the list of overlays information. + */ +public class OverlayManagerImpl { + private static final String TAG = "OverlayManagerImpl"; + private static final boolean DEBUG = false; + + private static final String FRRO_EXTENSION = ".frro"; + + private static final String IDMAP_EXTENSION = ".idmap"; + + @VisibleForTesting(visibility = PRIVATE) + public static final String SELF_TARGET = ".self_target"; + + @NonNull + private final Context mContext; + private Path mBasePath; + + /** + * Init a OverlayManagerImpl by the context. + * + * @param context the context to create overlay environment + */ + @VisibleForTesting(visibility = PACKAGE) + public OverlayManagerImpl(@NonNull Context context) { + mContext = Objects.requireNonNull(context); + + if (!Process.myUserHandle().equals(context.getUser())) { + throw new SecurityException("Self-Targeting doesn't support multiple user now!"); + } + } + + private static void cleanExpiredOverlays(Path selfTargetingBasePath, + Path folderForCurrentBaseApk) { + try { + final String currentBaseFolder = folderForCurrentBaseApk.toString(); + final String selfTargetingDir = selfTargetingBasePath.getFileName().toString(); + Files.walkFileTree( + selfTargetingBasePath, + new SimpleFileVisitor<>() { + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + throws IOException { + final String fileName = dir.getFileName().toString(); + return fileName.equals(currentBaseFolder) + ? FileVisitResult.SKIP_SUBTREE + : super.preVisitDirectory(dir, attrs); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + if (!file.toFile().delete()) { + Log.w(TAG, "Failed to delete file " + file); + } + return super.visitFile(file, attrs); + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) + throws IOException { + final String fileName = dir.getFileName().toString(); + if (!fileName.equals(currentBaseFolder) + && !fileName.equals(selfTargetingDir)) { + if (!dir.toFile().delete()) { + Log.w(TAG, "Failed to delete dir " + dir); + } + } + return super.postVisitDirectory(dir, exc); + } + }); + } catch (IOException e) { + Log.w(TAG, "Unknown fail " + e); + } + } + + /** + * Ensure the base dir for self-targeting is valid. + */ + @VisibleForTesting + public void ensureBaseDir() { + final String baseApkPath = mContext.getApplicationInfo().getBaseCodePath(); + final Path baseApkFolderName = Path.of(baseApkPath).getParent().getFileName(); + final File selfTargetingBaseFile = mContext.getDir(SELF_TARGET, MODE_PRIVATE); + Preconditions.checkArgument( + selfTargetingBaseFile.isDirectory() + && selfTargetingBaseFile.exists() + && selfTargetingBaseFile.canWrite() + && selfTargetingBaseFile.canRead() + && selfTargetingBaseFile.canExecute(), + "Can't work for this context"); + cleanExpiredOverlays(selfTargetingBaseFile.toPath(), baseApkFolderName); + + final File baseFile = new File(selfTargetingBaseFile, baseApkFolderName.toString()); + if (!baseFile.exists()) { + if (!baseFile.mkdirs()) { + Log.w(TAG, "Failed to create directory " + baseFile); + } + + // It fails to create frro and idmap files without this setting. + FileUtils.setPermissions( + baseFile, + FileUtils.S_IRWXU, + -1 /* uid unchanged */, + -1 /* gid unchanged */); + } + Preconditions.checkArgument( + baseFile.isDirectory() + && baseFile.exists() + && baseFile.canWrite() + && baseFile.canRead() + && baseFile.canExecute(), // 'list' capability + "Can't create a workspace for this context"); + + mBasePath = baseFile.toPath(); + } + + /** + * Check if the overlay name is valid or not. + * + * @param name the non-check overlay name + * @return the valid overlay name + */ + private static String checkOverlayNameValid(@NonNull String name) { + final String overlayName = + Preconditions.checkStringNotEmpty( + name, "overlayName should be neither empty nor null string"); + final String checkOverlayNameResult = + FrameworkParsingPackageUtils.validateName( + overlayName, false /* requireSeparator */, true /* requireFilename */); + Preconditions.checkArgument( + checkOverlayNameResult == null, + TextUtils.formatSimple( + "Invalid overlayName \"%s\". The check result is %s.", + overlayName, checkOverlayNameResult)); + return overlayName; + } + + private void checkPackageName(@NonNull String packageName) { + Preconditions.checkStringNotEmpty(packageName); + Preconditions.checkArgument( + TextUtils.equals(mContext.getPackageName(), packageName), + TextUtils.formatSimple( + "UID %d doesn't own the package %s", Process.myUid(), packageName)); + } + + /** + * Save FabricatedOverlay instance as frro and idmap files. + * + * @param overlayInternal the FabricatedOverlayInternal to be saved. + */ + public void registerFabricatedOverlay(@NonNull FabricatedOverlayInternal overlayInternal) + throws IOException, PackageManager.NameNotFoundException { + ensureBaseDir(); + Objects.requireNonNull(overlayInternal); + final List<FabricatedOverlayInternalEntry> entryList = + Objects.requireNonNull(overlayInternal.entries); + Preconditions.checkArgument(!entryList.isEmpty(), "overlay entries shouldn't be empty"); + final String overlayName = checkOverlayNameValid(overlayInternal.overlayName); + checkPackageName(overlayInternal.packageName); + checkPackageName(overlayInternal.targetPackageName); + + final ApplicationInfo applicationInfo = mContext.getApplicationInfo(); + final String targetPackage = Preconditions.checkStringNotEmpty( + applicationInfo.getBaseCodePath()); + final Path frroPath = mBasePath.resolve(overlayName + FRRO_EXTENSION); + final Path idmapPath = mBasePath.resolve(overlayName + IDMAP_EXTENSION); + + createFrroFile(frroPath.toString(), overlayInternal); + try { + createIdmapFile(targetPackage, frroPath.toString(), idmapPath.toString(), overlayName); + } catch (IOException e) { + if (!frroPath.toFile().delete()) { + Log.w(TAG, "Failed to delete file " + frroPath); + } + throw e; + } + } + + /** + * Remove the overlay with the specific name + * + * @param overlayName the specific name + */ + public void unregisterFabricatedOverlay(@NonNull String overlayName) { + ensureBaseDir(); + checkOverlayNameValid(overlayName); + final Path frroPath = mBasePath.resolve(overlayName + FRRO_EXTENSION); + final Path idmapPath = mBasePath.resolve(overlayName + IDMAP_EXTENSION); + + if (!frroPath.toFile().delete()) { + Log.w(TAG, "Failed to delete file " + frroPath); + } + if (!idmapPath.toFile().delete()) { + Log.w(TAG, "Failed to delete file " + idmapPath); + } + } + + /** + * Get the list of overlays information for the target package name. + * + * @param targetPackage the target package name + * @return the list of overlays information. + */ + @NonNull + public List<OverlayInfo> getOverlayInfosForTarget(@NonNull String targetPackage) { + ensureBaseDir(); + + final File base = mBasePath.toFile(); + final File[] frroFiles = base.listFiles((dir, name) -> { + if (!name.endsWith(FRRO_EXTENSION)) { + return false; + } + + final String idmapFileName = name.substring(0, name.length() - FRRO_EXTENSION.length()) + + IDMAP_EXTENSION; + final File idmapFile = new File(dir, idmapFileName); + return idmapFile.exists(); + }); + + final ArrayList<OverlayInfo> overlayInfos = new ArrayList<>(); + for (File file : frroFiles) { + final FabricatedOverlayInfo fabricatedOverlayInfo; + try { + fabricatedOverlayInfo = getFabricatedOverlayInfo(file.getAbsolutePath()); + } catch (IOException e) { + Log.w(TAG, "can't load " + file); + continue; + } + if (!TextUtils.equals(targetPackage, fabricatedOverlayInfo.targetPackageName)) { + continue; + } + if (DEBUG) { + Log.i(TAG, "load " + file); + } + + final OverlayInfo overlayInfo = + new OverlayInfo( + fabricatedOverlayInfo.packageName, + fabricatedOverlayInfo.overlayName, + fabricatedOverlayInfo.targetPackageName, + fabricatedOverlayInfo.targetOverlayable, + null, + file.getAbsolutePath(), + OverlayInfo.STATE_ENABLED, + UserHandle.myUserId(), + DEFAULT_PRIORITY, + true /* isMutable */, + true /* isFabricated */); + overlayInfos.add(overlayInfo); + } + return overlayInfos; + } + + private static native void createFrroFile( + @NonNull String frroFile, @NonNull FabricatedOverlayInternal fabricatedOverlayInternal) + throws IOException; + + private static native void createIdmapFile( + @NonNull String targetPath, + @NonNull String overlayPath, + @NonNull String idmapPath, + @NonNull String overlayName) + throws IOException; + + private static native FabricatedOverlayInfo getFabricatedOverlayInfo( + @NonNull String overlayPath) throws IOException; +} diff --git a/core/java/com/android/internal/os/TimeoutRecord.java b/core/java/com/android/internal/os/TimeoutRecord.java index 680f8fe6535f..a587834e2df2 100644 --- a/core/java/com/android/internal/os/TimeoutRecord.java +++ b/core/java/com/android/internal/os/TimeoutRecord.java @@ -40,7 +40,8 @@ public class TimeoutRecord { TimeoutKind.SERVICE_START, TimeoutKind.SERVICE_EXEC, TimeoutKind.CONTENT_PROVIDER, - TimeoutKind.APP_REGISTERED}) + TimeoutKind.APP_REGISTERED, + TimeoutKind.SHORT_FGS_TIMEOUT}) @Retention(RetentionPolicy.SOURCE) public @interface TimeoutKind { @@ -51,6 +52,7 @@ public class TimeoutRecord { int SERVICE_EXEC = 5; int CONTENT_PROVIDER = 6; int APP_REGISTERED = 7; + int SHORT_FGS_TIMEOUT = 8; } /** Kind of timeout, e.g. BROADCAST_RECEIVER, etc. */ @@ -144,4 +146,10 @@ public class TimeoutRecord { public static TimeoutRecord forApp(@NonNull String reason) { return TimeoutRecord.endingApproximatelyNow(TimeoutKind.APP_REGISTERED, reason); } + + /** Record for a "short foreground service" timeout. */ + @NonNull + public static TimeoutRecord forShortFgsTimeout(String reason) { + return TimeoutRecord.endingNow(TimeoutKind.SHORT_FGS_TIMEOUT, reason); + } } diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index 4b1753a82762..9cb2e68229f0 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -17,7 +17,7 @@ package com.android.internal.telephony; import android.telephony.BarringInfo; -import android.telephony.CallAttributes; +import android.telephony.CallState; import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.DataConnectionRealTimeInfo; @@ -62,7 +62,7 @@ oneway interface IPhoneStateListener { void onPhoneCapabilityChanged(in PhoneCapability capability); void onActiveDataSubIdChanged(in int subId); void onRadioPowerStateChanged(in int state); - void onCallAttributesChanged(in CallAttributes callAttributes); + void onCallStatesChanged(in List<CallState> callStateList); @SuppressWarnings(value={"untyped-collection"}) void onEmergencyNumberListChanged(in Map emergencyNumberList); void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber, int subscriptionId); diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index c7fa757ac0b7..7ba26866ee03 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -66,8 +66,8 @@ interface ITelephonyRegistry { void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation); @UnsupportedAppUsage void notifyCellInfo(in List<CellInfo> cellInfo); - void notifyPreciseCallState(int phoneId, int subId, int ringingCallState, - int foregroundCallState, int backgroundCallState); + void notifyPreciseCallState(int phoneId, int subId, in int[] callStates, in String[] imsCallIds, + in int[] imsCallServiceTypes, in int[] imsCallTypes); void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, int preciseDisconnectCause); void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); diff --git a/core/jni/Android.bp b/core/jni/Android.bp index d8b91c7dca79..f140e7980f52 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -215,6 +215,7 @@ cc_library_shared { "android_content_res_ResourceTimer.cpp", "android_security_Scrypt.cpp", "com_android_internal_content_om_OverlayConfig.cpp", + "com_android_internal_content_om_OverlayManagerImpl.cpp", "com_android_internal_expresslog_Counter.cpp", "com_android_internal_net_NetworkUtilsInternal.cpp", "com_android_internal_os_ClassLoaderFactory.cpp", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index f549cd828e7d..9e563dec3e4e 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -198,6 +198,7 @@ extern int register_android_security_Scrypt(JNIEnv *env); extern int register_com_android_internal_content_F2fsUtils(JNIEnv* env); extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env); extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env); +extern int register_com_android_internal_content_om_OverlayManagerImpl(JNIEnv* env); extern int register_com_android_internal_expresslog_Counter(JNIEnv* env); extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env); extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env); @@ -1587,6 +1588,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_SharedMemory), REG_JNI(register_android_os_incremental_IncrementalManager), REG_JNI(register_com_android_internal_content_om_OverlayConfig), + REG_JNI(register_com_android_internal_content_om_OverlayManagerImpl), REG_JNI(register_com_android_internal_expresslog_Counter), REG_JNI(register_com_android_internal_net_NetworkUtilsInternal), REG_JNI(register_com_android_internal_os_ClassLoaderFactory), diff --git a/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp b/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp new file mode 100644 index 000000000000..df55e424f2ed --- /dev/null +++ b/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <dlfcn.h> + +#include <optional> + +#define LOG_TAG "OverlayManagerImpl" + +#include "android-base/no_destructor.h" +#include "androidfw/ResourceTypes.h" +#include "core_jni_helpers.h" +#include "jni.h" + +namespace android { + +static struct fabricated_overlay_internal_offsets_t { + jclass classObject; + jfieldID packageName; + jfieldID overlayName; + jfieldID targetPackageName; + jfieldID targetOverlayable; + jfieldID entries; +} gFabricatedOverlayInternalOffsets; + +static struct fabricated_overlay_internal_entry_offsets_t { + jclass classObject; + jfieldID resourceName; + jfieldID dataType; + jfieldID data; + jfieldID stringData; + jfieldID binaryData; + jfieldID configuration; +} gFabricatedOverlayInternalEntryOffsets; + +static struct parcel_file_descriptor_offsets_t { + jclass classObject; + jmethodID getFd; +} gParcelFileDescriptorOffsets; + +static struct List_offsets_t { + jclass classObject; + jmethodID size; + jmethodID get; +} gListOffsets; + +static struct fabricated_overlay_info_offsets_t { + jclass classObject; + jmethodID constructor; + jfieldID packageName; + jfieldID overlayName; + jfieldID targetPackageName; + jfieldID targetOverlayable; + jfieldID path; +} gFabricatedOverlayInfoOffsets; + +namespace self_targeting { + +constexpr const char kIOException[] = "java/io/IOException"; +constexpr const char IllegalArgumentException[] = "java/lang/IllegalArgumentException"; + +class DynamicLibraryLoader { +public: + explicit DynamicLibraryLoader(JNIEnv* env) { + /* For SelfTargeting, there are 2 types of files to be handled. One is frro and the other is + * idmap. For creating frro/idmap files and reading frro files, it needs libandroid_runtime + * to do a shared link to libidmap2. However, libidmap2 contains the codes generated from + * google protocol buffer. When libandroid_runtime does a shared link to libidmap2, it will + * impact the memory for system_server and zygote(a.k.a. all applications). + * + * Not all applications need to either create/read frro files or create idmap files all the + * time. When the apps apply the SelfTargeting overlay effect, it only needs libandroifw + * that is loaded. To use dlopen(libidmap2.so) is to make sure that applications don't + * impact themselves' memory by loading libidmap2 until they need to create/read frro files + * or create idmap files. + */ + handle_ = dlopen("libidmap2.so", RTLD_NOW); + if (handle_ == nullptr) { + jniThrowNullPointerException(env); + return; + } + + createIdmapFileFuncPtr_ = + reinterpret_cast<CreateIdmapFileFunc>(dlsym(handle_, "CreateIdmapFile")); + if (createIdmapFileFuncPtr_ == nullptr) { + jniThrowNullPointerException(env, "The symbol CreateIdmapFile is not found."); + return; + } + getFabricatedOverlayInfoFuncPtr_ = reinterpret_cast<GetFabricatedOverlayInfoFunc>( + dlsym(handle_, "GetFabricatedOverlayInfo")); + if (getFabricatedOverlayInfoFuncPtr_ == nullptr) { + jniThrowNullPointerException(env, "The symbol GetFabricatedOverlayInfo is not found."); + return; + } + createFrroFile_ = reinterpret_cast<CreateFrroFileFunc>(dlsym(handle_, "CreateFrroFile")); + if (createFrroFile_ == nullptr) { + jniThrowNullPointerException(env, "The symbol CreateFrroFile is not found."); + return; + } + } + + bool callCreateFrroFile(std::string& out_error, const std::string& packageName, + const std::string& overlayName, const std::string& targetPackageName, + const std::optional<std::string>& targetOverlayable, + const std::vector<FabricatedOverlayEntryParameters>& entries_params, + const std::string& frro_file_path) { + return createFrroFile_(out_error, packageName, overlayName, targetPackageName, + targetOverlayable, entries_params, frro_file_path); + } + + bool callCreateIdmapFile(std::string& out_error, const std::string& targetPath, + const std::string& overlayPath, const std::string& idmapPath, + const std::string& overlayName) { + return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName); + } + + bool callGetFabricatedOverlayInfo(std::string& out_error, const std::string& overlay_path, + OverlayManifestInfo& out_overlay_manifest_info) { + return getFabricatedOverlayInfoFuncPtr_(out_error, overlay_path, out_overlay_manifest_info); + } + + explicit operator bool() const { + return handle_ != nullptr && createFrroFile_ != nullptr && + createIdmapFileFuncPtr_ != nullptr && getFabricatedOverlayInfoFuncPtr_ != nullptr; + } + + DynamicLibraryLoader(const DynamicLibraryLoader&) = delete; + + DynamicLibraryLoader& operator=(const DynamicLibraryLoader&) = delete; + + ~DynamicLibraryLoader() { + if (handle_ != nullptr) { + dlclose(handle_); + } + } + +private: + typedef bool (*CreateFrroFileFunc)( + std::string& out_error, const std::string& packageName, const std::string& overlayName, + const std::string& targetPackageName, + const std::optional<std::string>& targetOverlayable, + const std::vector<FabricatedOverlayEntryParameters>& entries_params, + const std::string& frro_file_path); + + typedef bool (*CreateIdmapFileFunc)(std::string& out_error, const std::string& targetPath, + const std::string& overlayPath, + const std::string& idmapPath, + const std::string& overlayName); + + typedef bool (*GetFabricatedOverlayInfoFunc)(std::string& out_error, + const std::string& overlay_path, + OverlayManifestInfo& out_overlay_manifest_info); + + void* handle_; + CreateFrroFileFunc createFrroFile_; + CreateIdmapFileFunc createIdmapFileFuncPtr_; + GetFabricatedOverlayInfoFunc getFabricatedOverlayInfoFuncPtr_; +}; + +static DynamicLibraryLoader& EnsureDynamicLibraryLoader(JNIEnv* env) { + static android::base::NoDestructor<DynamicLibraryLoader> loader(env); + return *loader; +} + +static std::optional<std::string> getNullableString(JNIEnv* env, jobject object, jfieldID field) { + auto javaString = reinterpret_cast<jstring>(env->GetObjectField(object, field)); + if (javaString == nullptr) { + return std::nullopt; + } + + const ScopedUtfChars result(env, javaString); + if (result.c_str() == nullptr) { + return std::nullopt; + } + + return std::optional<std::string>{result.c_str()}; +} + +static std::optional<android::base::borrowed_fd> getNullableFileDescriptor(JNIEnv* env, + jobject object, + jfieldID field) { + auto binaryData = env->GetObjectField(object, field); + if (binaryData == nullptr) { + return std::nullopt; + } + + return env->CallIntMethod(binaryData, gParcelFileDescriptorOffsets.getFd); +} + +static void CreateFrroFile(JNIEnv* env, jclass /*clazz*/, jstring jsFrroFilePath, jobject overlay) { + DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env); + if (!dlLoader) { + jniThrowNullPointerException(env, "libidmap2 is not loaded"); + return; + } + + if (overlay == nullptr) { + jniThrowNullPointerException(env, "overlay is null"); + return; + } + auto jsPackageName = + (jstring)env->GetObjectField(overlay, gFabricatedOverlayInternalOffsets.packageName); + const ScopedUtfChars packageName(env, jsPackageName); + if (packageName.c_str() == nullptr) { + jniThrowNullPointerException(env, "packageName is null"); + return; + } + auto jsOverlayName = + (jstring)env->GetObjectField(overlay, gFabricatedOverlayInternalOffsets.overlayName); + const ScopedUtfChars overlayName(env, jsOverlayName); + if (overlayName.c_str() == nullptr) { + jniThrowNullPointerException(env, "overlayName is null"); + return; + } + auto jsTargetPackageName = + (jstring)env->GetObjectField(overlay, + gFabricatedOverlayInternalOffsets.targetPackageName); + const ScopedUtfChars targetPackageName(env, jsTargetPackageName); + if (targetPackageName.c_str() == nullptr) { + jniThrowNullPointerException(env, "targetPackageName is null"); + return; + } + auto overlayable = + getNullableString(env, overlay, gFabricatedOverlayInternalOffsets.targetOverlayable); + const ScopedUtfChars frroFilePath(env, jsFrroFilePath); + if (frroFilePath.c_str() == nullptr) { + jniThrowNullPointerException(env, "frroFilePath is null"); + return; + } + jobject entries = env->GetObjectField(overlay, gFabricatedOverlayInternalOffsets.entries); + if (entries == nullptr) { + jniThrowNullPointerException(env, "overlay entries is null"); + return; + } + const jint size = env->CallIntMethod(entries, gListOffsets.size); + ALOGV("frroFilePath = %s, packageName = %s, overlayName = %s, targetPackageName = %s," + " targetOverlayable = %s, size = %d", + frroFilePath.c_str(), packageName.c_str(), overlayName.c_str(), targetPackageName.c_str(), + overlayable.value_or(std::string()).c_str(), size); + + std::vector<FabricatedOverlayEntryParameters> entries_params; + for (jint i = 0; i < size; i++) { + jobject entry = env->CallObjectMethod(entries, gListOffsets.get, i); + auto jsResourceName = reinterpret_cast<jstring>( + env->GetObjectField(entry, gFabricatedOverlayInternalEntryOffsets.resourceName)); + const ScopedUtfChars resourceName(env, jsResourceName); + const auto dataType = + env->GetIntField(entry, gFabricatedOverlayInternalEntryOffsets.dataType); + + // In Java, the data type is int but the maximum value of data Type is less than 0xff. + if (dataType >= UCHAR_MAX) { + jniThrowException(env, IllegalArgumentException, "Unsupported data type"); + return; + } + + const auto data = env->GetIntField(entry, gFabricatedOverlayInternalEntryOffsets.data); + auto configuration = + getNullableString(env, entry, gFabricatedOverlayInternalEntryOffsets.configuration); + auto string_data = + getNullableString(env, entry, gFabricatedOverlayInternalEntryOffsets.stringData); + auto binary_data = + getNullableFileDescriptor(env, entry, + gFabricatedOverlayInternalEntryOffsets.binaryData); + entries_params.push_back( + FabricatedOverlayEntryParameters{resourceName.c_str(), (DataType)dataType, + (DataValue)data, + string_data.value_or(std::string()), binary_data, + configuration.value_or(std::string())}); + ALOGV("resourceName = %s, dataType = 0x%08x, data = 0x%08x, dataString = %s," + " binaryData = %d, configuration = %s", + resourceName.c_str(), dataType, data, string_data.value_or(std::string()).c_str(), + binary_data.has_value(), configuration.value_or(std::string()).c_str()); + } + + std::string err_result; + if (!dlLoader.callCreateFrroFile(err_result, packageName.c_str(), overlayName.c_str(), + targetPackageName.c_str(), overlayable, entries_params, + frroFilePath.c_str())) { + jniThrowException(env, IllegalArgumentException, err_result.c_str()); + return; + } +} + +static void CreateIdmapFile(JNIEnv* env, jclass /* clazz */, jstring jsTargetPath, + jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName) { + DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env); + if (!dlLoader) { + jniThrowNullPointerException(env, "libidmap2 is not loaded"); + return; + } + + const ScopedUtfChars targetPath(env, jsTargetPath); + if (targetPath.c_str() == nullptr) { + jniThrowNullPointerException(env, "targetPath is null"); + return; + } + const ScopedUtfChars overlayPath(env, jsOverlayPath); + if (overlayPath.c_str() == nullptr) { + jniThrowNullPointerException(env, "overlayPath is null"); + return; + } + const ScopedUtfChars idmapPath(env, jsIdmapPath); + if (idmapPath.c_str() == nullptr) { + jniThrowNullPointerException(env, "idmapPath is null"); + return; + } + const ScopedUtfChars overlayName(env, jsOverlayName); + if (overlayName.c_str() == nullptr) { + jniThrowNullPointerException(env, "overlayName is null"); + return; + } + ALOGV("target_path = %s, overlay_path = %s, idmap_path = %s, overlay_name = %s", + targetPath.c_str(), overlayPath.c_str(), idmapPath.c_str(), overlayName.c_str()); + + std::string err_result; + if (!dlLoader.callCreateIdmapFile(err_result, targetPath.c_str(), overlayPath.c_str(), + idmapPath.c_str(), overlayName.c_str())) { + jniThrowException(env, kIOException, err_result.c_str()); + return; + } +} + +static jobject GetFabricatedOverlayInfo(JNIEnv* env, jclass /* clazz */, jstring jsOverlayPath) { + const ScopedUtfChars overlay_path(env, jsOverlayPath); + if (overlay_path.c_str() == nullptr) { + jniThrowNullPointerException(env, "overlay_path is null"); + return nullptr; + } + ALOGV("overlay_path = %s", overlay_path.c_str()); + + DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env); + if (!dlLoader) { + return nullptr; + } + + std::string err_result; + OverlayManifestInfo overlay_manifest_info; + if (!dlLoader.callGetFabricatedOverlayInfo(err_result, overlay_path.c_str(), + overlay_manifest_info) != 0) { + jniThrowException(env, kIOException, err_result.c_str()); + return nullptr; + } + jobject info = env->NewObject(gFabricatedOverlayInfoOffsets.classObject, + gFabricatedOverlayInfoOffsets.constructor); + jstring jsOverName = env->NewStringUTF(overlay_manifest_info.name.c_str()); + jstring jsPackageName = env->NewStringUTF(overlay_manifest_info.package_name.c_str()); + jstring jsTargetPackage = env->NewStringUTF(overlay_manifest_info.target_package.c_str()); + jstring jsTargetOverlayable = env->NewStringUTF(overlay_manifest_info.target_name.c_str()); + env->SetObjectField(info, gFabricatedOverlayInfoOffsets.overlayName, jsOverName); + env->SetObjectField(info, gFabricatedOverlayInfoOffsets.packageName, jsPackageName); + env->SetObjectField(info, gFabricatedOverlayInfoOffsets.targetPackageName, jsTargetPackage); + env->SetObjectField(info, gFabricatedOverlayInfoOffsets.targetOverlayable, jsTargetOverlayable); + env->SetObjectField(info, gFabricatedOverlayInfoOffsets.path, jsOverlayPath); + return info; +} + +} // namespace self_targeting + +// JNI registration. +static const JNINativeMethod gOverlayManagerMethods[] = { + {"createFrroFile", "(Ljava/lang/String;Landroid/os/FabricatedOverlayInternal;)V", + reinterpret_cast<void*>(self_targeting::CreateFrroFile)}, + {"createIdmapFile", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", + reinterpret_cast<void*>(self_targeting::CreateIdmapFile)}, + {"getFabricatedOverlayInfo", "(Ljava/lang/String;)Landroid/os/FabricatedOverlayInfo;", + reinterpret_cast<void*>(self_targeting::GetFabricatedOverlayInfo)}, +}; + +int register_com_android_internal_content_om_OverlayManagerImpl(JNIEnv* env) { + jclass ListClass = FindClassOrDie(env, "java/util/List"); + gListOffsets.classObject = MakeGlobalRefOrDie(env, ListClass); + gListOffsets.size = GetMethodIDOrDie(env, gListOffsets.classObject, "size", "()I"); + gListOffsets.get = + GetMethodIDOrDie(env, gListOffsets.classObject, "get", "(I)Ljava/lang/Object;"); + + jclass fabricatedOverlayInternalClass = + FindClassOrDie(env, "android/os/FabricatedOverlayInternal"); + gFabricatedOverlayInternalOffsets.classObject = + MakeGlobalRefOrDie(env, fabricatedOverlayInternalClass); + gFabricatedOverlayInternalOffsets.packageName = + GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "packageName", + "Ljava/lang/String;"); + gFabricatedOverlayInternalOffsets.overlayName = + GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "overlayName", + "Ljava/lang/String;"); + gFabricatedOverlayInternalOffsets.targetPackageName = + GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "targetPackageName", + "Ljava/lang/String;"); + gFabricatedOverlayInternalOffsets.targetOverlayable = + GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "targetOverlayable", + "Ljava/lang/String;"); + gFabricatedOverlayInternalOffsets.entries = + GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "entries", + "Ljava/util/List;"); + + jclass fabricatedOverlayInternalEntryClass = + FindClassOrDie(env, "android/os/FabricatedOverlayInternalEntry"); + gFabricatedOverlayInternalEntryOffsets.classObject = + MakeGlobalRefOrDie(env, fabricatedOverlayInternalEntryClass); + gFabricatedOverlayInternalEntryOffsets.resourceName = + GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "resourceName", + "Ljava/lang/String;"); + gFabricatedOverlayInternalEntryOffsets.dataType = + GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "dataType", + "I"); + gFabricatedOverlayInternalEntryOffsets.data = + GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "data", "I"); + gFabricatedOverlayInternalEntryOffsets.stringData = + GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "stringData", + "Ljava/lang/String;"); + gFabricatedOverlayInternalEntryOffsets.binaryData = + GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "binaryData", + "Landroid/os/ParcelFileDescriptor;"); + gFabricatedOverlayInternalEntryOffsets.configuration = + GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, + "configuration", "Ljava/lang/String;"); + + jclass parcelFileDescriptorClass = + android::FindClassOrDie(env, "android/os/ParcelFileDescriptor"); + gParcelFileDescriptorOffsets.classObject = MakeGlobalRefOrDie(env, parcelFileDescriptorClass); + gParcelFileDescriptorOffsets.getFd = + GetMethodIDOrDie(env, gParcelFileDescriptorOffsets.classObject, "getFd", "()I"); + + jclass fabricatedOverlayInfoClass = FindClassOrDie(env, "android/os/FabricatedOverlayInfo"); + gFabricatedOverlayInfoOffsets.classObject = MakeGlobalRefOrDie(env, fabricatedOverlayInfoClass); + gFabricatedOverlayInfoOffsets.constructor = + GetMethodIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "<init>", "()V"); + gFabricatedOverlayInfoOffsets.packageName = + GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "packageName", + "Ljava/lang/String;"); + gFabricatedOverlayInfoOffsets.overlayName = + GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "overlayName", + "Ljava/lang/String;"); + gFabricatedOverlayInfoOffsets.targetPackageName = + GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "targetPackageName", + "Ljava/lang/String;"); + gFabricatedOverlayInfoOffsets.targetOverlayable = + GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "targetOverlayable", + "Ljava/lang/String;"); + gFabricatedOverlayInfoOffsets.path = + GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "path", + "Ljava/lang/String;"); + + return RegisterMethodsOrDie(env, "com/android/internal/content/om/OverlayManagerImpl", + gOverlayManagerMethods, NELEM(gOverlayManagerMethods)); +} + +} // namespace android diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 285258a979e4..556636ddd210 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -88,6 +88,7 @@ message SecureSettingsProto { optional SettingProto odi_captions_volume_ui_enabled = 42 [ (android.privacy).dest = DEST_AUTOMATIC ]; // Setting for accessibility magnification for following typing. optional SettingProto accessibility_magnification_follow_typing_enabled = 43 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto contrast_level = 44 [ (android.privacy).dest = DEST_AUTOMATIC ]; } optional Accessibility accessibility = 2; diff --git a/core/res/res/layout-watch/alert_dialog_progress_material.xml b/core/res/res/layout-watch/alert_dialog_progress_material.xml new file mode 100644 index 000000000000..686156cfa4c5 --- /dev/null +++ b/core/res/res/layout-watch/alert_dialog_progress_material.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:paddingStart="?attr/dialogPreferredPadding" + android:paddingTop="@dimen/dialog_padding_top_material" + android:paddingEnd="?attr/dialogPreferredPadding" + android:paddingBottom="@dimen/dialog_padding_top_material"> + <TextView + android:id="@+id/progress_dialog_message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_centerInParent="true" + style="@style/ProgressDialogMessage" /> + <ProgressBar + android:id="@+id/progress" + style="?attr/progressBarStyleHorizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_centerHorizontal="true" /> + <TextView + android:id="@+id/progress_percent" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@id/progress" /> + <TextView + android:id="@+id/progress_number" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_below="@id/progress" /> +</RelativeLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 3ad6dc3dc244..37220ed27286 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Laat die program toe om dele van ditself deurdringend in die geheue te hou. Dit kan geheue wat aan ander programme beskikbaar is, beperk, en die foon stadiger maak."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"laat loop voorgronddiens"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Laat die program toe om van voorgronddienste gebruik te maak."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"gebruik voorgronddienstipe “kamera”"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Laat die app toe om die voorgronddienstipe “kamera” te gebruik"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"gebruik voorgronddienstipe “gekoppelde toestel”"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Laat die app toe om die voorgronddienstipe “gekoppelde toestel” te gebruik"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"gebruik voorgronddienstipe “datasinkronisering”"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Laat die app toe om die voorgronddienstipe “datasinkronisering” te gebruik"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"gebruik voorgronddienstipe “ligging”"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Laat die app toe om die voorgronddienstipe “ligging” te gebruik"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"gebruik voorgronddienstipe “mediaterugspeel”"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Laat die app toe om die voorgronddienstipe “mediaterugspeel” te gebruik"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"gebruik voorgronddienstipe “mediaprojeksie”"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Laat die app toe om die voorgronddienstipe “mediaprojeksie” te gebruik"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"gebruik voorgronddienstipe “mikrofoon”"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Laat die app toe om die voorgronddienstipe “mikrofoon” te gebruik"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"gebruik voorgronddienstipe “foonoproep”"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Laat die app toe om die voorgronddienstipe “foonoproep” te gebruik"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"gebruik voorgronddienstipe “gesondheid”"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Laat die app toe om die voorgronddienstipe “gesondheid” te gebruik"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"gebruik voorgronddienstipe “afstandboodskappe”"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Laat die app toe om die voorgronddienstipe “afstandboodskappe” te gebruik"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"gebruik voorgronddienstipe “stelselvrystelling”"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Laat die app toe om die voorgronddienstipe “stelselvrystelling” te gebruik"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"gebruik voorgronddienstipe “spesiale gebruik”"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Laat die app toe om die voorgronddienstipe “spesiale gebruik” te gebruik"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"meet programberging-ruimte"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Laat die program toe om sy kode, data en kasgroottes op te haal"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"verander stelsel-instellings"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Hierdie die program kan oudio met die mikrofoon opneem terwyl die program gebruik word."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"neem oudio op die agtergrond op"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Hierdie program kan enige tyd oudio met die mikrofoon opneem."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"bespeur skermskote van appvensters"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Hierdie app sal ingelig word as ’n skermskoot geneem word terwyl die app gebruik word."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"stuur bevele na die SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Laat die program toe om bevele na die SIM te stuur. Dit is baie gevaarlik."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"herken fisieke aktiwiteit"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan nie toegang tot die foon se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan nie toegang tot die tablet se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Jy kan nie toegang hiertoe kry terwyl daar gestroom word nie. Probeer eerder op jou foon."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Kan nie prent-in-prent sien terwyl jy stroom nie"</string> <string name="system_locale_title" msgid="711882686834677268">"Stelselverstek"</string> <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 9a3cfd0d250b..49a0b7abbe86 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -495,10 +495,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ይህ መተግበሪያ መተግበሪያው ስራ ላይ ሳለ ማይክሮፎኑን በመጠቀም ኦዲዮን መቅዳት ይችላል።"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"በበስተጀርባ ኦዲዮን ይቅዱ"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"ይህ መተግበሪያ በማናቸውም ጊዜ ማይክራፎኑን በመጠቀም ኦዲዮን መቅዳት ይችላል።"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"የመተግበሪያ መስኮቶች የማያ ገጽ ቀረጻዎችን ማወቅ"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"መተግበሪያው በጥቅም ላይ ሳለ ቅጽበታዊ ገጽ እይታ ሲነሳ ይህ መተግበሪያ ማሳወቂያ ይደርሰዋል።"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"ወደ ሲሙ ትዕዛዞችን መላክ"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"መተግበሪያው ትዕዛዞችን ወደ ሲሙ እንዲልክ ያስችለዋል። ይሄ በጣማ አደገኛ ነው።"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"አካላዊ እንቅስቃሴን ለይቶ ማወቅ"</string> @@ -2342,8 +2340,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"የስልኩን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ጡባዊውን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ዥረት በመልቀቅ ላይ ሳለ ይህ ሊደረስበት አይችልም። በምትኩ በስልክዎ ላይ ይሞክሩ።"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"በዥረት በመልቀቅ ወቅት በስዕል-ላይ-ስዕል ማየት አይችሉም"</string> <string name="system_locale_title" msgid="711882686834677268">"የሥርዓት ነባሪ"</string> <string name="default_card_name" msgid="9198284935962911468">"ካርድ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index d14299319ba8..1db09f1a06a0 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -399,54 +399,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"للسماح للتطبيق بجعل أجزاء منه ثابتة في الذاكرة. وقد يؤدي هذا إلى تقييد الذاكرة المتاحة للتطبيقات الأخرى مما يؤدي إلى حدوث بطء في الهاتف."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"تشغيل الخدمة في المقدمة"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"للسماح للتطبيق بالاستفادة من الخدمات التي تعمل في المقدمة."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"camera\"."</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"connectedDevice\"."</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"dataSync\"."</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"location\"."</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"mediaPlayback\"."</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"mediaProjection\"."</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"microphone\"."</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"phoneCall\"."</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"health\"."</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"remoteMessaging\"."</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"systemExempted\"."</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"تشغيل الخدمة التي تعمل في المقدّمة ذات النوع \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"يسمح هذا الإذن للتطبيق بالاستفادة من الخدمات التي تعمل في المقدّمة ذات النوع \"specialUse\"."</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"قياس مساحة تخزين التطبيق"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"للسماح للتطبيق باسترداد شفرته وبياناته وأحجام ذاكرات التخزين المؤقت"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"تعديل إعدادات النظام"</string> @@ -499,10 +475,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"يمكن لهذا التطبيق تسجيل الصوت باستخدام الميكروفون عندما يكون التطبيق قيد الاستخدام."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"تسجيل الصوت في الخلفية"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"يمكن لهذا التطبيق تسجيل الصوت باستخدام الميكروفون في أي وقت."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"رصد لقطات الشاشة لنوافذ التطبيق"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"سيتم إشعار هذا التطبيق عند التقاط لقطة شاشة أثناء استخدام التطبيق."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"إرسال أوامر إلى شريحة SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"السماح للتطبيق بإرسال أوامر إلى شريحة SIM. وهذا أمر بالغ الخطورة."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"التعرّف على النشاط البدني"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 2d740ec4d12a..9a0dbfad02b6 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"মেম\'ৰিত নিজৰ বাবে প্ৰয়োজনীয় ঠাই পৃথক কৰিবলৈ এপক অনুমতি দিয়ে। এই কার্যই ফ\'নৰ কার্যক লেহেমীয়া কৰি অন্য এপবোৰৰ বাবে উপলব্ধ মেম\'ৰিক সীমাবদ্ধ কৰে।"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"অগ্ৰভূমিৰ সেৱা চলাব পাৰে"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"এপ্টোক অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে।"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"কেমেৰা\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"এপ্টোক \"কেমেৰা\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"এপ্টোক \"connectedDevice\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"এপ্টোক \"dataSync\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"অৱস্থান\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"এপ্টোক \"অৱস্থান\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"এপ্টোক \"mediaPlayback\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"এপ্টোক \"mediaProjection\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"মাইক্ৰ’ফ’ন\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"এপ্টোক \"মাইক্ৰ’ফ’ন\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"এপ্টোক \"phoneCall\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"স্বাস্থ্য\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"এপ্টোক \"স্বাস্থ্য\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"এপ্টোক \"remoteMessaging\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"কেমেৰা\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"এপ্টোক \"systemExempted\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ চলাওক"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"এপ্টোক \"specialUse\" সম্পৰ্কীয় অগ্ৰভূমি সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"এপৰ ষ্ট’ৰেজৰ খালী ঠাই হিচাপ কৰক"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"এপ্টোক ইয়াৰ ক\'ড, ডেটা আৰু কেশ্বৰ আকাৰ বিচাৰি উলিয়াবলৈ অনুমতি দিয়ে"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ছিষ্টেম ছেটিংহ সংশোধন কৰক"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"এই এপ্টোৱে ইয়াক ব্যৱহাৰ কৰি থাকোঁতে মাইক্ৰ’ফ’ন ব্যৱহাৰ কৰি অডিঅ’ ৰেকর্ড কৰিব পাৰে।"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"নেপথ্যত অডিঅ’ ৰেকৰ্ড কৰক"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"এই এপ্টোৱে যিকোনো সময়তে মাইক্ৰ’ফ’ন ব্যৱহাৰ কৰি অডিঅ’ ৰেকৰ্ড কৰিব পাৰে।"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"এপৰ ৱিণ্ড’সমূহৰ স্ক্ৰীনৰ ফট’ তোলাটো চিনাক্ত কৰক"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"এই এপ্টো ব্যৱহাৰ হৈ থকাৰ সময়ত কোনো স্ক্ৰীনশ্বট ল’লে, ইয়াক জনোৱা হয়।"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"ছিমলৈ নিৰ্দেশ পঠিয়াব পাৰে"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"ছিমলৈ নিৰ্দেশসমূহ প্ৰেৰণ কৰিবলৈ এপক অনুমতি দিয়ে। ই অতি ক্ষতিকাৰক।"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"শাৰীৰিক কাৰ্যকলাপ চিনাক্ত কৰক"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা ফ’নটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা টেবলেটটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ষ্ট্ৰীম কৰি থকাৰ সময়ত এইটো এক্সেছ কৰিব নোৱাৰি। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"ষ্ট্ৰীম কৰি থকাৰ সময়ত picture-in-picture চাব নোৱাৰি"</string> <string name="system_locale_title" msgid="711882686834677268">"ছিষ্টেম ডিফ’ল্ট"</string> <string name="default_card_name" msgid="9198284935962911468">"কাৰ্ড <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 772bbb4efbce..bcee616c7696 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Tətbiqə öz komponentlərini yaddaşda saxlama icazəsi verir. Bu digər tətbiqlər üçün mövcud olan yaddaşı limitləyə bilər."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ön fon xidmətindən istifadə edin"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Tətbiqə ön fon xidmətlərini işlətmək icazəsi verin."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"kamera\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Tətbiqə \"kamera\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Tətbiqə \"connectedDevice\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Tətbiqə \"dataSync\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"məkan\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Tətbiqə \"məkan\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Tətbiqə \"mediaPlayback\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Tətbiqə \"mediaProjection\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"mikrofon\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Tətbiqə \"mikrofon\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Tətbiqə \"phoneCall\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"sağlamlıq\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Tətbiqə \"sağlamlıq\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Tətbiqə \"remoteMessaging\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Tətbiqə \"systemExempted\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" növü olan ön fon xidmətləri işlətmək"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Tətbiqə \"specialUse\" növü olan ön fon xidmətlərini işlətmək icazəsi verir"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"tətbiq saxlama yaddaşını ölçmək"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Tətbiqə özünün kodunu, məlumatını və keş ölçüsünü alma icazəsi verir."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"Sistem ayarlarının dəyişdirilməsi"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Bu tətbiq istifadə edilən zaman mikrofondan istifadə edərək audio yaza bilər."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"arxa fonda audio yazmaq"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Bu tətbiq istənilən zaman mikrofondan istifadə edərək audio yaza bilər."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"tətbiq pəncərələrinin ekran şəkillərini aşkar edin"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Tətbiq istifadə edilərkən skrinşot çəkildikdə bu tətbiqə bildiriş göndəriləcək."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"əmrləri SIM\'ə göndərin"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Tətbiqə SIM-ə əmrlər göndərməyə imkan verir. Bu, çox təhlükəlidir."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"fiziki fəaliyyəti tanıyın"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına giriş etmək olmur"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan planşetin kamerasına giriş etmək olmur"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Yayım zamanı buna giriş mümkün deyil. Telefonunuzda sınayın."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Yayım zamanı şəkildə şəkilə baxmaq mümkün deyil"</string> <string name="system_locale_title" msgid="711882686834677268">"Sistem defoltu"</string> <string name="default_card_name" msgid="9198284935962911468">"KART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 13523f85b462..4267c7d47cea 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Dozvoljava aplikaciji da učini sopstvene komponente trajnim u memoriji. Ovo može da ograniči memoriju dostupnu drugim aplikacijama i uspori telefon."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"pokreni uslugu u prvom planu"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Dozvoljava aplikaciji da koristi usluge u prvom planu."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"pokretanje usluge u prvom planu koja pripada tipu „camera“"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „camera“"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"pokretanje usluge u prvom planu koja pripada tipu „connectedDevice“"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „connectedDevice“"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"pokretanje usluge u prvom planu koja pripada tipu „dataSync“"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „dataSync“"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"pokretanje usluge u prvom planu koja pripada tipu „location“"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „location“"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"pokretanje usluge u prvom planu koja pripada tipu „mediaPlayback“"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „mediaPlayback“"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"pokretanje usluge u prvom planu koja pripada tipu „mediaProjection“"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „mediaProjection“"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"pokretanje usluge u prvom planu koja pripada tipu „microphone“"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „microphone“"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"pokretanje usluge u prvom planu koja pripada tipu „phoneCall“"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „phoneCall“"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"pokretanje usluge u prvom planu koja pripada tipu „health“"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „health“"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"pokretanje usluge u prvom planu koja pripada tipu „remoteMessaging“"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „remoteMessaging“"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"pokretanje usluge u prvom planu koja pripada tipu „systemExempted“"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „systemExempted“"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"pokretanje usluge u prvom planu koja pripada tipu „specialUse“"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Dozvoljava aplikaciji da koristi usluge u prvom planu koje pripadaju tipu „specialUse“"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"merenje memorijskog prostora u aplikaciji"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Dozvoljava aplikaciji da preuzme veličine kôda, podataka i keša."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"izmena podešavanja sistema"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ova aplikacija može da snima zvuk pomoću mikrofona dok se aplikacija koristi."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"da snima zvuk u pozadini"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ova aplikacija može da snima zvuk pomoću mikrofona u bilo kom trenutku."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"otkrivanje snimanja ekrana u prozorima aplikacija"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ako se tokom korišćenja ove aplikacije napravi snimak ekrana, aplikacija će dobiti obaveštenje."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"slanje komandi na SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Omogućava aplikaciji da šalje komande SIM kartici. To je veoma opasno."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičkih aktivnosti"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ne može da se pristupi kameri telefona sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ne može da se pristupi kameri tableta sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Ovom ne možete da pristupate tokom strimovanja. Probajte na telefonu."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Ne možete da gledate sliku u slici pri strimovanju"</string> <string name="system_locale_title" msgid="711882686834677268">"Podrazumevani sistemski"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index e2ee1f498574..e99c1cb22c23 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Дазваляе прыкладанню захоўваць некаторыя пастаянныя часткi ў памяцi. Гэта можа абмежаваць аб\'ём памяці, даступнай для іншых прыкладанняў, i запаволiць працу тэлефона."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"запусціць актыўныя сэрвісы"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Дазваляе праграме выкарыстоўваць асноўныя сэрвісы."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"запуск актыўнага сэрвісу тыпу \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"запуск актыўнага сэрвісу тыпу \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"запуск актыўнага сэрвісу тыпу \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"запуск актыўнага сэрвісу тыпу \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"запуск актыўнага сэрвісу тыпу \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"запуск актыўнага сэрвісу тыпу \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"запуск актыўнага сэрвісу тыпу \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"запуск актыўнага сэрвісу тыпу \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"запуск актыўнага сэрвісу тыпу \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"запуск актыўнага сэрвісу тыпу \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"запуск актыўнага сэрвісу тыпу \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"запуск актыўнага сэрвісу тыпу \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Дазваляе праграме выкарыстоўваць актыўныя сэрвісы тыпу \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"вымерыць прастору для захоўвання прыкладання"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Дазваляе прыкладанням атрымліваць яго код, дадзеныя і аб\'ём кэш-памяці"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"змена сістэмных налад"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Гэта праграма падчас яе выкарыстання можа запісваць аўдыя з дапамогай мікрафона."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"запісваць аўдыя ў фонавым рэжыме"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Гэта праграма можа ў любы час запісваць аўдыя з дапамогай мікрафона."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"выяўляць здыманне экрана з вокнамі праграмы"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Калі ў час выкарыстання гэтай праграмы будзе зроблены здымак экрана, паявіцца апавяшчэнне."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"адпраўляць каманды на SIM-карту"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Дазваляе праграме адпраўляць каманды SIM-карце. Гэта вельмі небяспечна."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"распазнаваць фізічную актыўнасць"</string> @@ -2344,8 +2318,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не ўдалося атрымаць доступ да камеры тэлефона з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не ўдалося атрымаць доступ да камеры планшэта з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string> <string name="vdm_secure_window" msgid="161700398158812314">"Не ўдаецца атрымаць доступ у час перадачы плынню. Паспрабуйце скарыстаць тэлефон."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Падчас перадачы плынню прагляд у рэжыме \"Відарыс у відарысе\" немагчымы"</string> <string name="system_locale_title" msgid="711882686834677268">"Стандартная сістэмная налада"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 0c56d0f9a243..5d1e8b5e0825 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Разрешава на приложението да прави части от себе си постоянни в паметта. Това може да ограничи наличната за другите приложения, забавяйки телефона."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"изпълнение на услуги на преден план"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Разрешава на приложението да се възползва от услуги на преден план."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"изпълнение на услуги на преден план от тип camera"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Разрешава на приложението да се възползва от услуги на преден план от тип camera"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"изпълнение на услуги на преден план от тип connectedDevice"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Разрешава на приложението да се възползва от услуги на преден план от тип connectedDevice"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"изпълнение на услуги на преден план от тип dataSync"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Разрешава на приложението да се възползва от услуги на преден план от тип dataSync"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"изпълнение на услуги на преден план от тип location"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Разрешава на приложението да се възползва от услуги на преден план от тип location"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"изпълнение на услуги на преден план от тип mediaPlayback"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Разрешава на приложението да се възползва от услуги на преден план от тип mediaPlayback"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"изпълнение на услуги на преден план от тип mediaProjection"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Разрешава на приложението да се възползва от услуги на преден план от тип mediaProjection"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"изпълнение на услуги на преден план от тип microphone"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Разрешава на приложението да се възползва от услуги на преден план от тип microphone"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"изпълнение на услуги на преден план от тип phoneCall"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Разрешава на приложението да се възползва от услуги на преден план от тип phoneCall"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"изпълнение на услуги на преден план от тип health"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Разрешава на приложението да се възползва от услуги на преден план от тип health"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"изпълнение на услуги на преден план от тип remoteMessaging"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Разрешава на приложението да се възползва от услуги на преден план от тип remoteMessaging"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"изпълнение на услуги на преден план от тип systemExempted"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Разрешава на приложението да се възползва от услуги на преден план от тип systemExempted"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"изпълнение на услуги на преден план от тип specialUse"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Разрешава на приложението да се възползва от услуги на преден план от тип specialUse"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"измерване на ползваното от приложението място в хранилището"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Разрешава на приложението да извлича размера на своя код, данни и кеш"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"промяна на системните настройки"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Когато се използва, това приложение може да записва аудио посредством микрофона."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"записва аудио на заден план"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Това приложение може по всяко време да записва аудио посредством микрофона."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"установяване на заснемания на екрана на прозорците на приложението"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Това приложение ще получава известия, когато по време на използването му бъде направена екранна снимка."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"изпращане на команди до SIM картата"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Разрешава на приложението да изпраща команди до SIM картата. Това е много опасно."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"разпознаване на физическата активност"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Няма достъп до камерата на телефона от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Няма достъп до камерата на таблета от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"До това съдържание не може да се осъществи достъп при поточно предаване. Вместо това опитайте от телефона си."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Функцията „Картина в картината“ не е налице при поточно предаване"</string> <string name="system_locale_title" msgid="711882686834677268">"Стандартно за системата"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 4751df7b9995..1ffe1507aad1 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"মেমরিতে নিজের জন্য প্রয়োজনীয় জায়গা আলাদা করে রাখতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ এর ফলে অন্যান্য অ্যাপ্লিকেশানগুলির জায়গা সীমিত হয়ে পড়তে পারে ও ফোনটি অপেক্ষাকৃত ধীরগতির হয়ে পড়তে পারে৷"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ফোরগ্রাউন্ডে পরিষেবা চালানো"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"অ্যাপটিকে ফোরগ্রাউন্ডের পরিষেবা ব্যবহার করতে দেয়।"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"অ্যাপকে \"camera\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"অ্যাপকে \"connectedDevice\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"অ্যাপকে \"dataSync\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"অ্যাপকে \"location\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"অ্যাপকে \"mediaPlayback\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"অ্যাপকে \"mediaProjection\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"অ্যাপকে \"microphone\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"অ্যাপকে \"phoneCall\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"অ্যাপকে \"health\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"অ্যাপকে \"remoteMessaging\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"অ্যাপকে \"systemExempted\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা রান করান"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"অ্যাপকে \"specialUse\" সম্পর্কিত ফোরগ্রাউন্ড পরিষেবা ব্যবহার করার অনুমতি দেয়"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"অ্যাপ্লিকেশন সঞ্চয়স্থানের জায়গা পরিমাপ করে"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"অ্যাপ্লিকেশানকে এটির কোড, ডেটা, এবং ক্যাশে মাপ উদ্ধার করার অনুমতি দেয়"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"সিস্টেম সেটিংস পরিবর্তন করুন"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"এই অ্যাপটি যখন ব্যবহার করা হচ্ছে, তখন মাইক্রোফোন ব্যবহার করে অডিও রেকর্ড করতে পারবে।"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ব্যাকগ্রাউন্ডে অডিও রেকর্ড করতে পারবে"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"এই অ্যাপটি মাইক্রোফোন ব্যবহার করে যেকোনও সময় অডিও রেকর্ড করতে পারবে।"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"অ্যাপ উইন্ডোর স্ক্রিন ক্যাপচার করা হলে তা শনাক্ত করা"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"অ্যাপ ব্যবহার করার সময় স্ক্রিনশট নেওয়া হলে এই অ্যাপে বিজ্ঞপ্তি পাঠানো হবে।"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"সিম এ আদেশগুলি পাঠান"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"অ্যাপ্লিকেশানটিকে সিম কার্ডে কমান্ডগুলি পাঠানোর অনুমতি দেয়৷ এটি খুবই বিপজ্জনক৷"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"শারীরিক অ্যাক্টিভিটি শনাক্ত করুন"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ফোনের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ট্যাবলেটের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string> <string name="vdm_secure_window" msgid="161700398158812314">"স্ট্রিমিংয়ের সময় এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ফোনে ব্যবহার করে দেখুন।"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"স্ট্রিম করার সময় \'ছবির-মধ্যে-ছবি\' দেখা যাবে না"</string> <string name="system_locale_title" msgid="711882686834677268">"সিস্টেম ডিফল্ট"</string> <string name="default_card_name" msgid="9198284935962911468">"কার্ড <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index acd9aa44eecc..f1523927430c 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Omogućava aplikaciji da neke svoje dijelove pohrani trajno u memoriji. Ovo može ograničiti veličinu raspoložive memorije za druge aplikacije i tako usporiti telefon."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"pokretanje usluge u prvom planu"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Dopušta aplikaciji korištenje usluga u prvom planu."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"pokreni uslugu u prvom planu s vrstom \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"pokreni uslugu u prvom planu s vrstom \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"pokreni uslugu u prvom planu s vrstom \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"pokreni uslugu u prvom planu s vrstom \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"pokreni uslugu u prvom planu s vrstom \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"pokreni uslugu u prvom planu s vrstom \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"pokreni uslugu u prvom planu s vrstom \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"pokreni uslugu u prvom planu s vrstom \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"pokreni uslugu u prvom planu s vrstom \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"pokreni uslugu u prvom planu s vrstom \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"pokreni uslugu u prvom planu s vrstom \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"pokreni uslugu u prvom planu s vrstom \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Dozvoljava aplikaciji da koristi usluge u prvom planu s vrstom \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"mjerenje prostora kojeg aplikacije zauzimaju u pohrani"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Dozvoljava aplikaciji preuzimanje svog koda, podataka i veličine keš memorije"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"izmjena postavki sistema"</string> @@ -496,8 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Za vrijeme korištenja, ova aplikacija može snimati zvuk koristeći mikrofon."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"snimanje zvuka u pozadini"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ova aplikacija može u svakom trenutku snimati zvuk koristeći mikrofon."</string> - <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"detektirati snimanja zaslona prozora aplikacije"</string> - <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ako se tijekom upotrebe ove aplikacije izradi snimka zaslona, aplikacija će dobiti obavijest."</string> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"otkrivanje snimanja ekrana u prozorima aplikacije"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Aplikacija će dobiti obavještenje kada se kreira snimak ekrana dok se aplikacija koristi."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"slanje komandi SIM kartici"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Omogućava aplikaciji slanje naredbi na SIM. Ovo je vrlo opasno."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičke aktivnosti"</string> @@ -2341,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nije moguće pristupiti kameri telefona s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nije moguće pristupiti kameri tableta s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Ovom ne možete pristupiti tokom prijenosa. Umjesto toga pokušajte na telefonu."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Tokom prijenosa nije moguće gledati sliku u slici"</string> <string name="system_locale_title" msgid="711882686834677268">"Sistemski zadano"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 18abb284b143..1f267acac3dc 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -495,10 +495,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Aquesta aplicació pot gravar àudio amb el micròfon mentre s\'està utilitzant."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar àudio en segon pla"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Aquesta aplicació pot gravar àudio amb el micròfon en qualsevol moment."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"detecta les captures de pantalla de les finestres d\'aplicacions"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Aquesta aplicació rebrà una notificació quan es faci una captura de pantalla mentre s\'utilitza l\'aplicació."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar ordres a la SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permet que l\'aplicació enviï ordres a la SIM. Això és molt perillós."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconèixer l\'activitat física"</string> @@ -2342,8 +2340,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No es pot accedir a la càmera del telèfon des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No es pot accedir a la càmera de la tauleta des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"No s\'hi pot accedir mentre s\'està reproduint en continu. Prova-ho al telèfon."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"No es pot veure el mode de pantalla en pantalla durant la reproducció en continu"</string> <string name="system_locale_title" msgid="711882686834677268">"Valor predeterminat del sistema"</string> <string name="default_card_name" msgid="9198284935962911468">"TARGETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index eae6dfb6fdfd..ff49c69e8b46 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Umožňuje aplikaci uložit některé své části trvale do paměti. Může to omezit paměť dostupnou pro ostatní aplikace a zpomalit tak telefon."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"spouštění služeb na popředí"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Povolte aplikaci využívání služeb na popředí."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"používat službu v popředí typu „camera“"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Umožňuje aplikaci používat služby v popředí typu „camera“"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"používat službu v popředí typu „connectedDevice“"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Umožňuje aplikaci používat služby v popředí typu „connectedDevice“"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"používat službu v popředí typu „dataSync“"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Umožňuje aplikaci používat služby v popředí typu „dataSync“"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"používat službu v popředí typu „location“"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Umožňuje aplikaci používat služby v popředí typu „location“"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"používat službu v popředí typu „mediaPlayback“"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Umožňuje aplikaci používat služby v popředí typu „mediaPlayback“"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"používat službu v popředí typu „mediaProjection“"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Umožňuje aplikaci používat služby v popředí typu „mediaProjection“"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"používat službu v popředí typu „microphone“"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Umožňuje aplikaci používat služby v popředí typu „microphone“"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"používat službu v popředí typu „phoneCall“"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Umožňuje aplikaci používat služby v popředí typu „phoneCall“"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"používat službu v popředí typu „health“"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Umožňuje aplikaci používat služby v popředí typu „health“"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"používat službu v popředí typu „remoteMessaging“"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Umožňuje aplikaci používat služby v popředí typu „remoteMessaging“"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"používat službu v popředí typu „systemExempted“"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Umožňuje aplikaci používat služby v popředí typu „systemExempted“"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"používat službu v popředí typu „specialUse“"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Umožňuje aplikaci používat služby v popředí typu „specialUse“"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"výpočet místa pro ukládání aplikací"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Umožňuje aplikaci načtení svého kódu, dat a velikostí mezipaměti."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"změna nastavení systému"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Tato aplikace může pomocí mikrofonu během svého používání zaznamenat zvuk."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"zaznamenávat zvuk na pozadí"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Tato aplikace může pomocí mikrofonu kdykoli zaznamenat zvuk."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"zjišťování záznamu obrazovky s okny aplikace"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Tato aplikace dostane oznámení v případě pořízení snímku obrazovky během používání aplikace."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"odesílání příkazů do SIM karty"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Umožňuje aplikaci odesílat příkazy na kartu SIM. Toto oprávnění je velmi nebezpečné."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"rozpoznávání fyzické aktivity"</string> @@ -2344,8 +2318,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu telefonu"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu tabletu"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Tento obsah při streamování nelze zobrazit. Zkuste to na telefonu."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Během streamování nelze zobrazit obraz v obraze"</string> <string name="system_locale_title" msgid="711882686834677268">"Výchozí nastavení systému"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 5e32ab6a156d..9c069e7367c4 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Tillader, at appen gør dele af sig selv vedholdende i hukommelsen. Dette kan begrænse den tilgængelige hukommelse for andre apps, hvilket gør telefonen langsommere."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"kør tjeneste i forgrunden"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Tillad, at appen anvender tjenester i forgrunden."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"kør tjenesten af typen \"camera\" i forgrunden"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Tillader, at appen benytter tjenester af typen \"camera\" i forgrunden"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"kør tjenesten af typen \"connectedDevice\" i forgrunden"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Tillader, at appen benytter tjenester af typen \"connectedDevice\" i forgrunden"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"kør tjenesten af typen \"dataSync\" i forgrunden"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Tillader, at appen benytter tjenester af typen \"dataSync\" i forgrunden"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"kør tjenesten af typen \"location\" i forgrunden"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Tillader, at appen benytter tjenester af typen \"location\" i forgrunden"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"kør tjenesten af typen \"mediaPlayback\" i forgrunden"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Tillader, at appen benytter tjenester af typen \"mediaPlayback\" i forgrunden"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"kør tjenesten af typen \"mediaProjection\" i forgrunden"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Tillader, at appen benytter tjenester af typen \"mediaProjection\" i forgrunden"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"kør tjenesten af typen \"microphone\" i forgrunden"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Tillader, at appen benytter tjenester af typen \"microphone\" i forgrunden"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"kør tjenesten af typen \"phoneCall\" i forgrunden"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Tillader, at appen benytter tjenester af typen \"phoneCall\" i forgrunden"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"kør tjenesten af typen \"health\" i forgrunden"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Tillader, at appen benytter tjenester af typen \"health\" i forgrunden"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"kør tjenesten af typen \"remoteMessaging\" i forgrunden"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Tillader, at appen benytter tjenester af typen \"remoteMessaging\" i forgrunden"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"kør tjenesten af typen \"systemExempted\" i forgrunden"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Tillader, at appen benytter tjenester af typen \"systemExempted\" i forgrunden"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"kør tjenesten af typen \"specialUse\" i forgrunden"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Tillader, at appen benytter tjenester af typen \"specialUse\" i forgrunden"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"måle appens lagerplads"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Tillader, at en app kan hente sin kode, data og cachestørrelser"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ændre systemindstillinger"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Denne app kan optage lyd med mikrofonen, mens appen er i brug."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"optag lyd i baggrunden"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Denne app kan optage lyd med mikrofonen når som helst."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"registrer screenshots af appvindue"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Denne app får en notifikation, når der tages et screenshot, mens appen er i brug."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"send kommandoer til SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Tillader, at appen sender kommandoer til SIM-kortet. Dette er meget farligt."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"genkend fysisk aktivitet"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kameraet på din telefon kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kameraet på din tablet kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Der er ikke adgang til dette indhold under streaming. Prøv på din telefon i stedet."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Funktionen Integreret billede er ikke tilgængelig, når der streames"</string> <string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string> <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index c4da5c858b2d..efc7e96d286c 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -495,10 +495,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Diese App darf mit dem Mikrofon Audioaufnahmen machen, solange sie verwendet wird."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Audioaufnahmen im Hintergrund machen"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Diese App darf mit dem Mikrofon jederzeit Audioaufnahmen machen."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"Bildschirmaufnahmen von App-Fenstern erkennen"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Diese App wird benachrichtigt, wenn ein Screenshot aufgenommen wird, während du sie verwendest."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"Befehle an die SIM senden"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Ermöglicht der App das Senden von Befehlen an die SIM-Karte. Dies ist äußerst risikoreich."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"Körperliche Aktivitäten erkennen"</string> @@ -2342,8 +2340,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Zugriff auf die Kamera des Smartphones über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Zugriff auf die Kamera des Tablets über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Während des Streamings ist kein Zugriff möglich. Versuch es stattdessen auf deinem Smartphone."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Funktion „Bild im Bild“ kann beim Streamen nicht verwendet werden"</string> <string name="system_locale_title" msgid="711882686834677268">"Standardeinstellung des Systems"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 91d8aaf61136..df8a6bb8b62f 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Επιτρέπει στην εφαρμογή να δημιουργεί μόνιμα τμήματα του εαυτού της στη μνήμη. Αυτό μπορεί να περιορίζει τη μνήμη που διατίθεται σε άλλες εφαρμογές, καθυστερώντας τη λειτουργία του τηλεφώνου."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"εκτέλεση υπηρεσίας προσκηνίου"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί υπηρεσίες προσκηνίου."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"εκτέλεση υπηρεσίας στο προσκήνιο με τον τύπο \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τις υπηρεσίες στο προσκήνιο με τον τύπο \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"υπολογίζει τον αποθηκευτικό χώρο εφαρμογής"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Επιτρέπει στην εφαρμογή να ανακτήσει τα μεγέθη κώδικα, δεδομένων και προσωρινής μνήμης"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"τροποποίηση ρυθμίσεων συστήματος"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Δεν είναι δυνατή η πρόσβαση στην κάμερα τηλεφώνου από το <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του tablet από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Δεν είναι δυνατή η πρόσβαση σε αυτό το στοιχείο κατά τη ροή. Δοκιμάστε στο τηλέφωνό σας."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Δεν είναι δυνατή η προβολή picture-in-picture κατά τη ροή"</string> <string name="system_locale_title" msgid="711882686834677268">"Προεπιλογή συστήματος"</string> <string name="default_card_name" msgid="9198284935962911468">"ΚΑΡΤΑ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 8ef72d151f3e..114c3756aea5 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Allows the app to make parts of itself persistent in memory. This can limit the memory available to other apps, slowing down the phone."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"run foreground service"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Allows the app to make use of foreground services."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"run foreground service with the type \'camera\'"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Allows the app to make use of foreground services with the type \'camera\'"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"run foreground service with the type \'connectedDevice\'"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Allows the app to make use of foreground services with the type \'connectedDevice\'"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"run foreground service with the type \'dataSync\'"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Allows the app to make use of foreground services with the type \'dataSync\'"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"run foreground service with the type \'location\'"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Allows the app to make use of foreground services with the type \'location\'"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"run foreground service with the type \'mediaPlayback\'"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Allows the app to make use of foreground services with the type \'mediaPlayback\'"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"run foreground service with the type \'mediaProjection\'"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Allows the app to make use of foreground services with the type \'mediaProjection\'"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"run foreground service with the type \'microphone\'"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Allows the app to make use of foreground services with the type \'microphone\'"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"run foreground service with the type \'phoneCall\'"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Allows the app to make use of foreground services with the type \'phoneCall\'"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"run foreground service with the type \'health\'"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Allows the app to make use of foreground services with the type \'health\'"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"run foreground service with the type \'remoteMessaging\'"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Allows the app to make use of foreground services with the type \'remoteMessaging\'"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"run foreground service with the type \'systemExempted\'"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Allows the app to make use of foreground services with the type \'systemExempted\'"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"run foreground service with the type \'specialUse\'"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Allows the app to make use of foreground services with the type \'specialUse\'"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"measure app storage space"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Allows the app to retrieve its code, data and cache sizes"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modify system settings"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index b16f3b6fce92..9c9f0668bf48 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the phone."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"run foreground service"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Allows the app to make use of foreground services."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"run foreground service with the type \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Allows the app to make use of foreground services with the type \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"run foreground service with the type \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Allows the app to make use of foreground services with the type \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"run foreground service with the type \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Allows the app to make use of foreground services with the type \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"run foreground service with the type \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Allows the app to make use of foreground services with the type \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"run foreground service with the type \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Allows the app to make use of foreground services with the type \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"run foreground service with the type \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Allows the app to make use of foreground services with the type \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"run foreground service with the type \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Allows the app to make use of foreground services with the type \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"run foreground service with the type \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Allows the app to make use of foreground services with the type \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"run foreground service with the type \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Allows the app to make use of foreground services with the type \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"run foreground service with the type \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Allows the app to make use of foreground services with the type \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"run foreground service with the type \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Allows the app to make use of foreground services with the type \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"run foreground service with the type \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Allows the app to make use of foreground services with the type \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"measure app storage space"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Allows the app to retrieve its code, data, and cache sizes"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modify system settings"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index fbc4aaeb6693..d11f7338e439 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Allows the app to make parts of itself persistent in memory. This can limit the memory available to other apps, slowing down the phone."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"run foreground service"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Allows the app to make use of foreground services."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"run foreground service with the type \'camera\'"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Allows the app to make use of foreground services with the type \'camera\'"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"run foreground service with the type \'connectedDevice\'"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Allows the app to make use of foreground services with the type \'connectedDevice\'"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"run foreground service with the type \'dataSync\'"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Allows the app to make use of foreground services with the type \'dataSync\'"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"run foreground service with the type \'location\'"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Allows the app to make use of foreground services with the type \'location\'"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"run foreground service with the type \'mediaPlayback\'"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Allows the app to make use of foreground services with the type \'mediaPlayback\'"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"run foreground service with the type \'mediaProjection\'"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Allows the app to make use of foreground services with the type \'mediaProjection\'"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"run foreground service with the type \'microphone\'"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Allows the app to make use of foreground services with the type \'microphone\'"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"run foreground service with the type \'phoneCall\'"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Allows the app to make use of foreground services with the type \'phoneCall\'"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"run foreground service with the type \'health\'"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Allows the app to make use of foreground services with the type \'health\'"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"run foreground service with the type \'remoteMessaging\'"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Allows the app to make use of foreground services with the type \'remoteMessaging\'"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"run foreground service with the type \'systemExempted\'"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Allows the app to make use of foreground services with the type \'systemExempted\'"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"run foreground service with the type \'specialUse\'"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Allows the app to make use of foreground services with the type \'specialUse\'"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"measure app storage space"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Allows the app to retrieve its code, data and cache sizes"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modify system settings"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 564a52dfecee..8dd085a66349 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Allows the app to make parts of itself persistent in memory. This can limit the memory available to other apps, slowing down the phone."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"run foreground service"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Allows the app to make use of foreground services."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"run foreground service with the type \'camera\'"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Allows the app to make use of foreground services with the type \'camera\'"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"run foreground service with the type \'connectedDevice\'"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Allows the app to make use of foreground services with the type \'connectedDevice\'"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"run foreground service with the type \'dataSync\'"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Allows the app to make use of foreground services with the type \'dataSync\'"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"run foreground service with the type \'location\'"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Allows the app to make use of foreground services with the type \'location\'"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"run foreground service with the type \'mediaPlayback\'"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Allows the app to make use of foreground services with the type \'mediaPlayback\'"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"run foreground service with the type \'mediaProjection\'"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Allows the app to make use of foreground services with the type \'mediaProjection\'"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"run foreground service with the type \'microphone\'"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Allows the app to make use of foreground services with the type \'microphone\'"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"run foreground service with the type \'phoneCall\'"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Allows the app to make use of foreground services with the type \'phoneCall\'"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"run foreground service with the type \'health\'"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Allows the app to make use of foreground services with the type \'health\'"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"run foreground service with the type \'remoteMessaging\'"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Allows the app to make use of foreground services with the type \'remoteMessaging\'"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"run foreground service with the type \'systemExempted\'"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Allows the app to make use of foreground services with the type \'systemExempted\'"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"run foreground service with the type \'specialUse\'"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Allows the app to make use of foreground services with the type \'specialUse\'"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"measure app storage space"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Allows the app to retrieve its code, data and cache sizes"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modify system settings"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index dc3462498f7a..2197501a7eb4 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the phone."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"run foreground service"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Allows the app to make use of foreground services."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"run foreground service with the type \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Allows the app to make use of foreground services with the type \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"run foreground service with the type \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Allows the app to make use of foreground services with the type \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"run foreground service with the type \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Allows the app to make use of foreground services with the type \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"run foreground service with the type \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Allows the app to make use of foreground services with the type \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"run foreground service with the type \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Allows the app to make use of foreground services with the type \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"run foreground service with the type \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Allows the app to make use of foreground services with the type \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"run foreground service with the type \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Allows the app to make use of foreground services with the type \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"run foreground service with the type \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Allows the app to make use of foreground services with the type \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"run foreground service with the type \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Allows the app to make use of foreground services with the type \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"run foreground service with the type \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Allows the app to make use of foreground services with the type \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"run foreground service with the type \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Allows the app to make use of foreground services with the type \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"run foreground service with the type \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Allows the app to make use of foreground services with the type \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"measure app storage space"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Allows the app to retrieve its code, data, and cache sizes"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modify system settings"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index f74ac2b6108b..0d72ec562096 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permite que la aplicación haga que algunas de sus partes se mantengan persistentes en la memoria. Esto puede limitar la memoria disponible para otras aplicaciones y ralentizar el dispositivo."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ejecutar servicio en primer plano"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permite que la app use servicios en primer plano."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"Ejecuta un servicio en primer plano con el tipo \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Permite que la app use servicios en primer plano con el tipo \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"Ejecuta un servicio en primer plano con el tipo \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Permite que la app use servicios en primer plano con el tipo \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"Ejecuta un servicio en primer plano con el tipo \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Permite que la app use servicios en primer plano con el tipo \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"Ejecuta un servicio en primer plano con el tipo \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Permite que la app use servicios en primer plano con el tipo \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"Ejecuta un servicio en primer plano con el tipo \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Permite que la app use servicios en primer plano con el tipo \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"Ejecuta un servicio en primer plano con el tipo \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Permite que la app use servicios en primer plano con el tipo \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"Ejecuta un servicio en primer plano con el tipo \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Permite que la app use servicios en primer plano con el tipo \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"Ejecuta un servicio en primer plano con el tipo \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Permite que la app use servicios en primer plano con el tipo \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"Ejecuta un servicio en primer plano con el tipo \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Permite que la app use servicios en primer plano con el tipo \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"Ejecuta un servicio en primer plano con el tipo \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Permite que la app use servicios en primer plano con el tipo \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"Ejecuta un servicio en primer plano con el tipo \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Permite que la app use servicios en primer plano con el tipo \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"Ejecuta un servicio en primer plano con el tipo \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Permite que la app use servicios en primer plano con el tipo \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"medir el espacio de almacenamiento de la aplicación"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permite que la aplicación recupere su código, sus datos y los tamaños de la memoria caché."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modificar la configuración del sistema"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Esta app puede grabar audio con el micrófono mientras está en uso."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"grabar audio en segundo plano"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Esta app puede grabar audio con el micrófono en cualquier momento."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"Detección de capturas de pantalla de las ventanas de la app"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Esta app recibirá una notificación cuando se tome una captura de pantalla mientras esté en uso."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos a la tarjeta SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que la aplicación envíe comandos a la tarjeta SIM. Usar este permiso es peligroso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconocer actividad física"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del dispositivo desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara de la tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"No se puede acceder a este contenido durante una transmisión. Inténtalo en tu teléfono."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"No puedes ver pantalla en pantalla mientras transmites"</string> <string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string> <string name="default_card_name" msgid="9198284935962911468">"TARJETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 42fb37dcff22..76495a8ac8d3 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -496,10 +496,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Esta aplicación puede grabar audio con el micrófono mientras la estés usando."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Grabar audio en segundo plano"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Esta aplicación puede grabar audio con el micrófono en cualquier momento."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"detectar capturas de pantalla de ventanas de la aplicación"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Esta aplicación recibirá un aviso cuando se haga una captura de pantalla mientras está en uso."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos a la tarjeta SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que la aplicación envíe comandos a la tarjeta SIM. Este permiso es muy peligroso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconocer actividad física"</string> @@ -2343,8 +2341,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del teléfono desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara del tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"No se puede acceder a este contenido durante una emisión. Prueba en tu teléfono."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"No se puede usar imagen en imagen mientras se emite contenido"</string> <string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string> <string name="default_card_name" msgid="9198284935962911468">"TARJETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index dd199d8fc6a7..c16f7fce6431 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Võimaldab rakendusel muuta oma osi mälus püsivaks. See võib piirata teistele (telefoni aeglasemaks muutvatele) rakendustele saadaolevat mälu."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"käita esiplaanil olevat teenust"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „camera“"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „camera“."</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „connectedDevice“"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „connectedDevice“."</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „dataSync“"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „dataSync“."</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „location“"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „location“."</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „mediaPlayback“"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „mediaPlayback“."</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „mediaProjection“"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „mediaProjection“."</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „microphone“"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „microphone“."</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „phoneCall“"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „phoneCall“."</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „health“"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „health“."</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „remoteMessaging“"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „remoteMessaging“."</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „systemExempted“"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „systemExempted“."</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"sellise esiplaanil oleva teenuse käitamine, mille tüüp on „specialUse“"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Lubab rakendusel kasutada esiplaanil olevaid teenuseid, mille tüüp on „specialUse“."</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"Rakenduse mäluruumi mõõtmine"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Võimaldab rakendusel tuua oma koodi, andmed ja vahemälu suurused"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"muutke süsteemi seadeid"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"See rakendus saab mikrofoniga heli salvestada siis, kui rakendus on kasutusel."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Taustal heli salvestamine."</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"See rakendus saab mikrofoniga heli salvestada mis tahes ajal."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"rakenduste akende puhul ekraanikuva jäädvustamise tuvastamine"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Rakendust teavitatakse, kui selle kasutamise ajal jäädvustatakse ekraanipilt."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM-kaardile käskluste saatmine"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Lubab rakendusel saata käske SIM-kaardile. See on väga ohtlik."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"füüsiliste tegevuste tuvastamine"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse telefoni kaamerale juurde."</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tahvelarvuti kaamerale juurde"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Sellele ei pääse voogesituse ajal juurde. Proovige juurde pääseda oma telefonis."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Voogesitamise ajal ei saa pilt pildis funktsiooni kasutada"</string> <string name="system_locale_title" msgid="711882686834677268">"Süsteemi vaikeseade"</string> <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 548ad2395906..2c29a807aec2 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta telefonoa motel daiteke."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"abiarazi zerbitzuak aurreko planoan"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Aurreko planoko zerbitzuak erabiltzea baimentzen dio aplikazioari."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"exekutatu aurreko planoko zerbitzu bat (camera motakoa)"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Aurreko planoko zerbitzuak (camera motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"exekutatu aurreko planoko zerbitzu bat (connectedDevice motakoa)"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Aurreko planoko zerbitzuak (connectedDevice motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"exekutatu aurreko planoko zerbitzu bat (dataSync motakoa)"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Aurreko planoko zerbitzuak (dataSync motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"exekutatu aurreko planoko zerbitzu bat (location motakoa)"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Aurreko planoko zerbitzuak (location motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"exekutatu aurreko planoko zerbitzu bat (mediaPlayback motakoa)"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Aurreko planoko zerbitzuak (mediaPlayback motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"exekutatu aurreko planoko zerbitzu bat (mediaProjection motakoa)"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Aurreko planoko zerbitzuak (mediaProjection motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"exekutatu aurreko planoko zerbitzu bat (microphone motakoa)"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Aurreko planoko zerbitzuak (microphone motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"exekutatu aurreko planoko zerbitzu bat (phoneCall motakoa)"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Aurreko planoko zerbitzuak (phoneCall motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"exekutatu aurreko planoko zerbitzu bat (health motakoa)"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Aurreko planoko zerbitzuak (health motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"exekutatu aurreko planoko zerbitzu bat (remoteMessaging motakoa)"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Aurreko planoko zerbitzuak (remoteMessaging motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"exekutatu aurreko planoko zerbitzu bat (systemExempted motakoa)"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Aurreko planoko zerbitzuak (systemExempted motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"exekutatu aurreko planoko zerbitzu bat (specialUse motakoa)"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Aurreko planoko zerbitzuak (specialUse motakoak) erabiltzeko baimena ematen dio aplikazioari"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"neurtu aplikazioen biltegiratzeko tokia"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Bere kodea, datuak eta cache-tamainak eskuratzeko baimena ematen die aplikazioei."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"aldatu sistemaren ezarpenak"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Aplikazioak abian den bitartean erabil dezake mikrofonoa audioa grabatzeko."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Audioa grabatu atzeko planoan."</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Aplikazioak edonoiz erabil dezake mikrofonoa audioa grabatzeko."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"hauteman pantaila-argazkiak aplikazioen leihoetan"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Aplikazioa erabili bitartean pantaila-argazki bat ateratzen denean, jakinarazpen bat jasoko duzu aplikazioan."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"bidali aginduak SIM txartelera"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"SIM txartelera aginduak bidaltzeko baimena ematen die aplikazioei. Oso arriskutsua da."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"hauteman jarduera fisikoa"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ezin da atzitu telefonoaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ezin da atzitu tabletaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Ezin da atzitu edukia hura igorri bitartean. Oraingo gailuaren ordez, erabili telefonoa."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Edukia zuzenean erreproduzitu bitartean ezin da pantaila txiki gainjarrian ikusi"</string> <string name="system_locale_title" msgid="711882686834677268">"Sistemaren balio lehenetsia"</string> <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g> TXARTELA"</string> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 07fa710f66ce..4ee442c534a4 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"به برنامه امکان میدهد قسمتهایی از خود را در حافظه دائمی کند. این کار حافظه موجود را برای سایر برنامهها محدود کرده و باعث کندی تلفن میشود."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"اجرای سرویس پیشزمینه"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"به برنامه اجازه میدهد از سرویسهای پیشزمینه استفاده کند."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"اجرای سرویس پیشنما از نوع «دوربین»"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «دوربین» استفاده کند"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"اجرای سرویس پیشنما از نوع «دستگاه متصل»"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «دستگاه متصل» استفاده کند"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"اجرای سرویس پیشنما از نوع «همگامسازی داده»"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «همگامسازی داده» استفاده کند"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"اجرای سرویس پیشنما از نوع «مکان»"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «مکان» استفاده کند"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"اجرای سرویس پیشنما از نوع «بازپخش رسانه»"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «بازپخش رسانه» استفاده کند"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"اجرای سرویس پیشنما از نوع «ارسال محتوا»"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «ارسال محتوا» استفاده کند"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"اجرای سرویس پیشنما از نوع «میکروفون»"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «میکروفون» استفاده کند"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"اجرای سرویس پیشنما از نوع «تماس تلفنی»"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «تماس تلفنی» استفاده کند"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"اجرای سرویس پیشنما از نوع «سلامتی»"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «سلامتی» استفاده کند"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"اجرای سرویس پیشنما از نوع «پیامرسانی ازراهدور»"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «پیامرسانی ازراهدور» استفاده کند"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"اجرای سرویس پیشنما از نوع «معافیت سیستم»"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «معافیت سیستم» استفاده کند"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"اجرای سرویس پیشنما از نوع «استفاده ویژه»"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"به برنامه اجازه میدهد از سرویسهای پیشنما از نوع «استفاده ویژه» استفاده کند"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"اندازهگیری اندازه فضای ذخیرهسازی برنامه"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"به برنامه اجازه میدهد تا کدها، دادهها و اندازههای حافظهٔ پنهان خود را بازیابی کند"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"تغییر تنظیمات سیستم"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"این برنامه وقتی درحال استفاده است، میتواند بااستفاده از میکروفون صدا ضبط کند."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ضبط صدا در پسزمینه"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"این برنامه میتواند در هرزمانی با استفاده از میکروفون صدا ضبط کند."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"تشخیص ضبط صفحهنمایش از پنجره برنامهها"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"وقتی نماگرفتی درحین استفاده از برنامه گرفته میشود، به این برنامه اطلاع داده میشود."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"ارسال فرمان به سیم کارت"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"به برنامه اجازه ارسال دستورات به سیم کارت را میدهد. این بسیار خطرناک است."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"تشخیص فعالیت فیزیکی"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"از <xliff:g id="DEVICE">%1$s</xliff:g> به دوربین تلفن دسترسی ندارید"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"نمیتوان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین رایانه لوحی دسترسی داشت"</string> <string name="vdm_secure_window" msgid="161700398158812314">"درحین جاریسازی، نمیتوانید به آن دسترسی داشته باشید. دسترسی به آن را در تلفنتان امتحان کنید."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"هنگام جاریسازی نمیتوان تصویر در تصویر را مشاهده کرد"</string> <string name="system_locale_title" msgid="711882686834677268">"پیشفرض سیستم"</string> <string name="default_card_name" msgid="9198284935962911468">"کارت <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index ce6e579496e8..158290df7d00 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Antaa sovelluksen lisätä omia osiaan muistiin pysyvästi. Tämä voi rajoittaa muiden sovellusten käytettävissä olevaa muistia ja hidastaa puhelimen toimintaa."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"suorita etualan palvelu"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Sallii sovelluksen käyttää etualan palveluja"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"käyttää etualan palveluja, joiden tyyppi on \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"käyttää etualan palveluja, joiden tyyppi on \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"käyttää etualan palveluja, joiden tyyppi on \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"käyttää etualan palveluja, joiden tyyppi on \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"käyttää etualan palveluja, joiden tyyppi on \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"käyttää etualan palveluja, joiden tyyppi on \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"käyttää etualan palveluja, joiden tyyppi on \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"käyttää etualan palveluja, joiden tyyppi on \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"käyttää etualan palveluja, joiden tyyppi on \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"käyttää etualan palveluja, joiden tyyppi on \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"käyttää etualan palveluja, joiden tyyppi on \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"käyttää etualan palveluja, joiden tyyppi on \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Sallii sovelluksen käyttää etualan palveluja, joiden tyyppi on \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"sovellusten tallennustilan mittaaminen"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Antaa sovelluksen noutaa sen koodin, tietojen ja välimuistin koot."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"muokkaa järjestelmän asetuksia"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Tämä sovellus voi tallentaa mikrofonilla audiota, kun sovellusta käytetään."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"tallentaa audiota taustalla"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Tämä sovellus voi tallentaa mikrofonilla audiota koska tahansa."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"havaitse sovelluksen ikkunoista otetut kuvakaappaukset"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Sovellukseen tulee ilmoitus, kun kuvakaappaus otetaan käytettäessä sovellusta."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"lähettää komentoja SIM-kortille"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Antaa sovelluksen lähettää komentoja SIM-kortille. Tämä ei ole turvallista."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"tunnistaa liikkumisen"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse puhelimen kameraan"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tabletin kameraan"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Sisältöön ei saa pääsyä striimauksen aikana. Kokeile striimausta puhelimella."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Pikkuruutua ei voi nähdä striimauksen aikana"</string> <string name="system_locale_title" msgid="711882686834677268">"Järjestelmän oletusarvo"</string> <string name="default_card_name" msgid="9198284935962911468">"Kortti: <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 51f6db884053..5f2d3dc2bdb5 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir le téléphone."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"exécuter le service en premier plan"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permet à l\'application d\'utiliser les services en premier plan."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"exécuter le service d\'avant-plan avec le type « appareil photo »"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appareil photo »"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"exécuter le service d\'avant-plan avec le type « appareil connecté »"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appareil connecté »"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"exécuter le service d\'avant-plan avec le type « synchronisation des données »"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « synchronisation des données »"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"exécuter le service d\'avant-plan avec le type « emplacement »"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « emplacement »"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"exécuter le service d\'avant-plan avec le type « lecture multimédia »"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « lecture multimédia »"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"exécuter le service d\'avant-plan avec le type « projection de contenus multimédias »"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « projection de contenus multimédias »"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"exécuter le service d\'avant-plan avec le type « microphone »"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « microphone »"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"exécuter le service d\'avant-plan avec le type « appel téléphonique »"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appel téléphonique »"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"exécuter le service d\'avant-plan avec le type « santé »"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « santé »"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"exécuter le service d\'avant-plan avec le type « messagerie à distance »"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « messagerie à distance »"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"exécuter le service d\'avant-plan avec le type « système exempté »"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « système exempté »"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"exécuter le service d\'avant-plan avec le type « usage spécial »"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « usage spécial »"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"évaluer l\'espace de stockage de l\'application"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permet à l\'application de récupérer la taille de son code, de ses données et de sa mémoire cache."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modifier les paramètres du système"</string> @@ -2169,7 +2145,7 @@ <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_lock_screen_label" msgid="5484190691945563838">"Écran de verrouillage"</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_headset_hook_label" msgid="8524691721287425468">"Crochet de casque d\'écoute"</string> <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Raccourci d\'accessibilité à l\'écran"</string> @@ -2341,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Vous ne pouvez pas y accéder lorsque vous utilisez la diffusion en continu. Essayez sur votre téléphone à la place."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Impossible d\'afficher des incrustations d\'image pendant une diffusion en continu"</string> <string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string> <string name="default_card_name" msgid="9198284935962911468">"CARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 8d84a396619c..563fa58396e0 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir le téléphone."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"exécuter un service de premier plan"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Autorise l\'application à utiliser des services de premier plan."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"exécuter un service de premier plan avec le type \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Autorise l\'appli à utiliser les services de premier plan avec le type \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"exécuter un service de premier plan avec le type \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Autorise l\'appli à utiliser les services de premier plan avec le type \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"exécuter un service de premier plan avec le type \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Autorise l\'appli à utiliser les services de premier plan avec le type \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"exécuter un service de premier plan avec le type \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Autorise l\'appli à utiliser les services de premier plan avec le type \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"exécuter un service de premier plan avec le type \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Autorise l\'appli à utiliser les services de premier plan avec le type \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"exécuter un service de premier plan avec le type \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Autorise l\'appli à utiliser les services de premier plan avec le type \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"exécuter un service de premier plan avec le type \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Autorise l\'appli à utiliser les services de premier plan avec le type \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"exécuter un service de premier plan avec le type \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Autorise l\'appli à utiliser les services de premier plan avec le type \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"exécuter un service de premier plan avec le type \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Autorise l\'appli à utiliser les services de premier plan avec le type \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"exécuter un service de premier plan avec le type \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Autorise l\'appli à utiliser les services de premier plan avec le type \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"exécuter un service de premier plan avec le type \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Autorise l\'appli à utiliser les services de premier plan avec le type \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"exécuter un service de premier plan avec le type \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Autorise l\'appli à utiliser les services de premier plan avec le type \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"évaluer l\'espace de stockage de l\'application"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permet à l\'application de récupérer son code, ses données et la taille de sa mémoire cache."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modifier les paramètres du système"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Cette application peut utiliser le micro pour réaliser des enregistrements audio quand elle est en cours d\'utilisation."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"réaliser des enregistrements audio en arrière-plan"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Cette application peut utiliser le micro pour réaliser des enregistrements audio à tout moment."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"détecter les captures d\'écran de fenêtres d\'appli"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Cette app sera notifiée lors de la prise d\'une capture d\'écran pendant son utilisation."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"envoyer des commandes à la carte SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Autoriser l\'envoi de commandes à la carte SIM via l\'application. Cette fonctionnalité est très risquée."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconnaître l\'activité physique"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Impossible d\'accéder à cela pendant le streaming. Essayez plutôt sur votre téléphone."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Impossible d\'afficher Picture-in-picture pendant le streaming"</string> <string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string> <string name="default_card_name" msgid="9198284935962911468">"CARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 57fba7f29276..a931219daf50 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permite á aplicación converter partes súas como persistentes na memoria. Esta acción pode limitar a cantidade memoria dispoñible para outras aplicacións e reducir a velocidade de funcionamento do teléfono."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"executar un servizo en primeiro plano"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permite que a aplicación utilice os servizos en primeiro plano."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"executar servizo en primeiro plano co tipo \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"executar servizo en primeiro plano co tipo \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"executar servizo en primeiro plano co tipo \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"executar servizo en primeiro plano co tipo \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"executar servizo en primeiro plano co tipo \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"executar servizo en primeiro plano co tipo \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"executar servizo en primeiro plano co tipo \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"executar servizo en primeiro plano co tipo \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"executar servizo en primeiro plano co tipo \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"executar servizo en primeiro plano co tipo \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"executar servizo en primeiro plano co tipo \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"executar servizo en primeiro plano co tipo \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Permite que a aplicación faga uso de servizos en primeiro plano co tipo \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"medir o espazo de almacenamento da aplicación"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permite á aplicación recuperar o código, os datos e os tamaños da caché"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modificar a configuración do sistema"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Mentres a empregas, esta aplicación pode utilizar o micrófono para gravar audio."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar audio en segundo plano"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Esta aplicación pode utilizar o micrófono en calquera momento para gravar audio."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"detectar capturas de pantalla de ventás da aplicación"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Esta aplicación recibirá unha notificación cando se faga unha captura de pantalla mentres se estea utilizando."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos á SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite á aplicación enviar comandos á SIM. Isto é moi perigoso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"recoñecer actividade física"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Non se puido acceder á cámara do teléfono desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Non se puido acceder á cámara da tableta desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Non se puido acceder a este contido durante a reprodución en tempo real. Téntao desde o teléfono."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Non se pode ver un vídeo en pantalla superposta mentres se reproduce en tempo real"</string> <string name="system_locale_title" msgid="711882686834677268">"Opción predeterminada do sistema"</string> <string name="default_card_name" msgid="9198284935962911468">"TARXETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index c89b02b0fe49..418eb48bcbe7 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"એપ્લિકેશનને મેમરીમાં પોતાના ભાગ સતત બનાવવાની મંજૂરી આપે છે. આ ફોનને ધીમો કરીને અન્ય ઍપ્લિકેશનો પર ઉપલબ્ધ મેમરીને સીમિત કરી શકે છે."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ઍપને ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"ઍપને \"camera\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"ઍપને \"connectedDevice\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"ઍપને \"dataSync\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"ઍપને \"location\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"ઍપને \"mediaPlayback\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"ઍપને \"mediaProjection\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"ઍપને \"microphone\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"ઍપને \"phoneCall\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"ઍપને \"health\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"ઍપને \"remoteMessaging\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"ઍપને \"systemExempted\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવા ચલાવો"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"ઍપને \"specialUse\" પ્રકારની પરવાનગી વડે ફૉરગ્રાઉન્ડ સેવાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ઍપ્લિકેશન સંગ્રહ સ્થાન માપો"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"એપ્લિકેશનને તેનો કોડ, ડેટા અને કેશ કદ પુનઃપ્રાપ્ત કરવાની મંજૂરી આપે છે."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"સિસ્ટમ સેટિંગમાં ફેરફાર કરો"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"આ ઍપ ઉપયોગમાં હોય ત્યારે તે માઇક્રોફોનનો ઉપયોગ કરીને ઑડિયો રેકોર્ડ કરી શકે છે."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"બૅકગ્રાઉન્ડમાં ઑડિયો રેકોર્ડ કરો"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"આ ઍપ, માઇક્રોફોનનો ઉપયોગ કરીને કોઈપણ સમયે ઑડિયો રેકોર્ડ કરી શકે છે."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ઍપ વિન્ડોના સ્ક્રીન કૅપ્ચરની ભાળ મેળવો"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"ઍપનો ઉપયોગ થઈ રહ્યો હોય ત્યારે સ્ક્રીનશૉટ લેવામાં આવે, તો આ ઍપને નોટિફિકેશન મળશે."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"સિમ ને આદેશો મોકલો"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"એપ્લિકેશનને સિમ પરા આદેશો મોકલવાની મંજૂરી આપે છે. આ ખૂબ જ ખતરનાક છે."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"શારીરિક પ્રવૃત્તિને ઓળખો"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ફોનના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ટૅબ્લેટના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string> <string name="vdm_secure_window" msgid="161700398158812314">"સ્ટ્રીમ કરતી વખતે આ ઍક્સેસ કરી શકાતું નથી. તેના બદલે તમારા ફોન પર પ્રયાસ કરો."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"સ્ટ્રીમ કરતી વખતે ચિત્ર-માં-ચિત્ર જોઈ શકતા નથી"</string> <string name="system_locale_title" msgid="711882686834677268">"સિસ્ટમ ડિફૉલ્ટ"</string> <string name="default_card_name" msgid="9198284935962911468">"કાર્ડ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index c544df4cfb7d..2406650a1ec5 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"ऐप्स को मेमोरी में स्वयं के कुछ हिस्सों को लगातार बनाने देता है. यह अन्य ऐप्स के लिए उपलब्ध स्मृति को सीमित कर फ़ोन को धीमा कर सकता है."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"स्क्रीन पर दिखने वाली सेवा चालू करें"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ऐप्लिकेशन को स्क्रीन पर दिखने वाली सेवाएं इस्तेमाल करने दें."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"इससे ऐप्लिकेशन, \"camera\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"इससे ऐप्लिकेशन, \"connectedDevice\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"इससे ऐप्लिकेशन, \"dataSync\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"इससे ऐप्लिकेशन, \"location\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"इससे ऐप्लिकेशन, \"mediaPlayback\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"इससे ऐप्लिकेशन, \"mediaProjection\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"इससे ऐप्लिकेशन, \"microphone\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"इससे ऐप्लिकेशन, \"phoneCall\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"इससे ऐप्लिकेशन, \"health\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"इससे ऐप्लिकेशन, \"remoteMessaging\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"इससे ऐप्लिकेशन, \"systemExempted\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" टाइप वाली फ़ोरग्राउंड सेवा को चलाने की अनुमति दें"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"इससे ऐप्लिकेशन, \"specialUse\" टाइप वाली फ़ोरग्राउंड सेवाओं का इस्तेमाल कर पाता है"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"पता करें कि ऐप मेमोरी में कितनी जगह है"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"ऐप को उसका कोड, डेटा, और कैश मेमोरी के आकारों को फिर से पाने देता है"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टम सेटिंग बदलें"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"जब इस ऐप्लिकेशन का इस्तेमाल किया जा रहा हो, तब यह माइक्रोफ़ोन का इस्तेमाल करके ऑडियो रिकॉर्ड कर सकता है."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ऐप्लिकेशन बैकग्राउंड में ऑडियो रिकॉर्ड कर सकता है"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"यह ऐप्लिकेशन जब चाहे, माइक्रोफ़ोन का इस्तेमाल करके ऑडियो रिकॉर्ड कर सकता है."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ऐप्लिकेशन विंडो के स्क्रीन कैप्चर का पता लगाने की अनुमति दें"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"अगर ऐप्लिकेशन का इस्तेमाल करते समय कोई स्क्रीनशॉट लिया जाता है, तो इसकी सूचना इस ऐप्लिकेशन पर दिखेगी."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"सिम पर निर्देश भेजें"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"ऐप को सिम पर निर्देश भेजने देती है. यह बहुत ही खतरनाक है."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"शरीर की गतिविधि को पहचानना"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से फ़ोन के कैमरे को ऐक्सेस नहीं किया जा सकता"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से टैबलेट के कैमरे को ऐक्सेस नहीं किया जा सकता"</string> <string name="vdm_secure_window" msgid="161700398158812314">"स्ट्रीमिंग के दौरान, इसे ऐक्सेस नहीं किया जा सकता. इसके बजाय, अपने फ़ोन पर ऐक्सेस करके देखें."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"स्ट्रीमिंग करते समय, \'पिक्चर में पिक्चर\' सुविधा इस्तेमाल नहीं की जा सकती"</string> <string name="system_locale_title" msgid="711882686834677268">"सिस्टम डिफ़ॉल्ट"</string> <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index e4679fe81d73..407eb4e6090d 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Aplikaciji omogućuje trajnu prisutnost nekih njenih dijelova u memoriji. To može ograničiti dostupnost memorije drugim aplikacijama i usporiti telefon."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"pokrenuti uslugu u prednjem planu"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Omogućuje aplikaciji da upotrebljava usluge koje su u prednjem planu."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"pokretanje usluge u prednjem planu s vrstom \"kamera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"fotoaparat\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"pokretanje usluge u prednjem planu s vrstom \"povezani uređaj\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"povezani uređaj\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"pokretanje usluge u prednjem planu s vrstom \"sinkroniziranje podataka\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"sinkroniziranje podataka\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"pokretanje usluge u prednjem planu s vrstom \"lokacija\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"lokacija\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"pokretanje usluge u prednjem planu s vrstom \"reprodukcija medijskih sadržaja\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"reprodukcija medijskih sadržaja\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"pokretanje usluge u prednjem planu s vrstom \"projekcija multimedija\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"projekcija multimedija\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"pokretanje usluge u prednjem planu s vrstom \"mikrofon\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"mikrofon\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"pokretanje usluge u prednjem planu s vrstom \"telefonski poziv\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"telefonski poziv\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"pokretanje usluge u prednjem planu s vrstom \"zdravlje\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"zdravlje\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"pokretanje usluge u prednjem planu s vrstom \"udaljena razmjena poruka\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"udaljena razmjena poruka\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"pokretanje usluge u prednjem planu s vrstom \"sustav je izuzeo\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"izuzeo sustav\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"pokretanje usluge u prednjem planu s vrstom \"posebna upotreba\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Omogućuje aplikaciji da iskoristi usluge u prednjem planu s vrstom \"posebna upotreba\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"mjerenje prostora za pohranu aplikacije"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Aplikaciji omogućuje dohvaćanje koda, podataka i veličine predmemorije"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"izmjena postavki sustava"</string> @@ -2341,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu telefona"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu tableta"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Sadržaju nije moguće pristupiti tijekom streaminga. Pokušajte mu pristupiti na telefonu."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Slika u slici ne može se prikazivati tijekom streaminga"</string> <string name="system_locale_title" msgid="711882686834677268">"Zadane postavke sustava"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 68bed0674904..34ee8a3106ad 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Lehetővé teszi az alkalmazás számára, hogy egyes részeit állandó jelleggel eltárolja a memóriában. Ez korlátozhatja a többi alkalmazás számára rendelkezésre álló memóriát, és lelassíthatja a telefont."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"előtérben lévő szolgáltatás futtatása"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"előtérben lévő szolgáltatás futtatása a következő típussal: „camera”"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „camera”"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"előtérben lévő szolgáltatás futtatása a következő típussal: „connectedDevice”"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „connectedDevice”"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"előtérben lévő szolgáltatás futtatása a következő típussal: „dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „dataSync”"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"előtérben lévő szolgáltatás futtatása a következő típussal: „location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „location”"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"előtérben lévő szolgáltatás futtatása a következő típussal: „mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „mediaPlayback”"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"előtérben lévő szolgáltatás futtatása a következő típussal: „mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „mediaProjection”"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"előtérben lévő szolgáltatás futtatása a következő típussal: „microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „microphone”"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"előtérben lévő szolgáltatás futtatása a következő típussal: „phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „phoneCall”"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"előtérben lévő szolgáltatás futtatása a következő típussal: „health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „health”"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"előtérben lévő szolgáltatás futtatása a következő típussal: „remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „remoteMessaging”"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"előtérben lévő szolgáltatás futtatása a következő típussal: „systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „systemExempted”"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"előtérben lévő szolgáltatás futtatása a következő típussal: „specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Engedélyezi az alkalmazásnak az előtérben lévő szolgáltatások használatát a következő típussal: „specialUse”"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"alkalmazás-tárhely felmérése"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Lehetővé teszi az alkalmazás számára a kód, az adatok és a gyorsítótár-méret lekérését"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"rendszerbeállítások módosítása"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Az alkalmazás a mikrofon használatával akkor készíthet hangfelvételt, amikor az alkalmazás használatban van."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"hangfelvétel készítése a háttérben"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Az alkalmazás a mikrofon használatával bármikor készíthet hangfelvételt."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"alkalmazásablakokról készült képernyőfelvétel észlelése"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ez az alkalmazás értesítést kap majd, amikor képernyőkép készül az alkalmazás használata közben."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"parancsok küldése a SIM-kártyára"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Engedélyezi, hogy az alkalmazás parancsokat küldjön a SIM kártyára. Ez rendkívül veszélyes lehet."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"testmozgás felismerése"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nem lehet hozzáférni a telefon kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nem lehet hozzáférni a táblagép kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Ehhez a tartalomhoz nem lehet hozzáférni streamelés közben. Próbálja újra a telefonján."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Streamelés közben nem lehetséges a kép a képben módban való lejátszás"</string> <string name="system_locale_title" msgid="711882686834677268">"Rendszerbeállítás"</string> <string name="default_card_name" msgid="9198284935962911468">"KÁRTYA: <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 4f053f34371b..91646a41e28d 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Թույլ է տալիս հավելվածին մնայուն դարձնել իր մասերը հիշողության մեջ: Սա կարող է սահմանափակել այլ հավելվածներին հասանելի հիշողությունը` դանդաղեցնելով հեռախոսի աշխատանքը:"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"աշխատեցնել ակտիվ ծառայությունները"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Թույլ է տալիս հավելվածին օգտագործել ակտիվ ծառայությունները:"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"գործարկել camera տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Հավելվածին թույլ է տալիս օգտագործել camera տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"գործարկել connectedDevice տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Հավելվածին թույլ է տալիս օգտագործել connectedDevice տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"գործարկել dataSync տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Հավելվածին թույլ է տալիս օգտագործել dataSync տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"գործարկել location տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Հավելվածին թույլ է տալիս օգտագործել location տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"գործարկել mediaPlayback տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Հավելվածին թույլ է տալիս օգտագործել mediaPlayback տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"գործարկել mediaProjection տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Հավելվածին թույլ է տալիս օգտագործել mediaProjection տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"գործարկել microphone տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Հավելվածին թույլ է տալիս օգտագործել microphone տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"գործարկել phoneCall տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Հավելվածին թույլ է տալիս օգտագործել phoneCall տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"գործարկել health տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Հավելվածին թույլ է տալիս օգտագործել health տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"գործարկել remoteMessaging տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Հավելվածին թույլ է տալիս օգտագործել remoteMessaging տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"գործարկել systemExempted տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Հավելվածին թույլ է տալիս օգտագործել systemExempted տեսակով ակտիվ ծառայությունները"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"գործարկել specialUse տեսակով ակտիվ ծառայությունները"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Հավելվածին թույլ է տալիս օգտագործել specialUse տեսակով ակտիվ ծառայությունները"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"չափել հավելվածի պահոցի տարածքը"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Թույլ է տալիս հավելվածին առբերել իր կոդը, տվյալները և քեշի չափերը"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"փոփոխել համակարգի կարգավորումները"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Այս հավելվածը կարող է օգտագործել խոսափողը՝ ձայնագրություններ անելու համար, միայն երբ հավելվածն ակտիվ է։"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ձայնագրել ֆոնային ռեժիմում"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Այս հավելվածը կարող է ցանկացած ժամանակ օգտագործել խոսափողը՝ ձայնագրություններ անելու համար։"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"հայտնաբերել հավելվածի պատուհանների էկրանի տեսագրումները"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Եթե հավելվածի օգտագործման ժամանակ սքրինշոթ արվի, հավելվածը ծանուցում կստանա։"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"ուղարկել հրամաններ SIM քարտին"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Թույլ է տալիս հավելվածին հրամաններ ուղարկել SIM-ին: Սա շատ վտանգավոր է:"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ֆիզիկական ակտիվության ճանաչում"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Հնարավոր չէ օգտագործել հեռախոսի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Հնարավոր չէ օգտագործել պլանշետի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Այս բովանդակությունը հասանելի չէ հեռարձակման ընթացքում։ Օգտագործեք ձեր հեռախոսը։"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Հեռարձակման ժամանակ հնարավոր չէ դիտել նկարը նկարի մեջ"</string> <string name="system_locale_title" msgid="711882686834677268">"Կանխադրված"</string> <string name="default_card_name" msgid="9198284935962911468">"ՔԱՐՏ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 882fb4172e2e..df7715bdce4c 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Memungkinkan aplikasi membuat bagian dari dirinya sendiri terus-menerus berada dalam memori. Izin ini dapat membatasi memori yang tersedia untuk aplikasi lain sehingga menjadikan ponsel lambat."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"jalankan layanan di latar depan"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Mengizinkan aplikasi menggunakan layanan di latar depan."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"menjalankan layanan latar depan dengan jenis \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"menjalankan layanan latar depan dengan jenis \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"menjalankan layanan latar depan dengan jenis \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"menjalankan layanan latar depan dengan jenis \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"menjalankan layanan latar depan dengan jenis \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"menjalankan layanan latar depan dengan jenis \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"menjalankan layanan latar depan dengan jenis \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"menjalankan layanan latar depan dengan jenis \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"menjalankan layanan latar depan dengan jenis \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"menjalankan layanan latar depan dengan jenis \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"menjalankan layanan latar depan dengan jenis \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"menjalankan layanan latar depan dengan jenis \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Mengizinkan aplikasi menggunakan layanan latar depan dengan jenis \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"mengukur ruang penyimpanan aplikasi"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Mengizinkan apl mengambil kode, data, dan ukuran temboloknya"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ubah setelan sistem"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Aplikasi ini dapat merekam audio menggunakan mikrofon saat aplikasi sedang digunakan."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"merekam audio di latar belakang"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Aplikasi ini dapat merekam audio menggunakan mikrofon kapan saja."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"mendeteksi screenshot jendela aplikasi"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Aplikasi ini akan diberi tahu saat screenshot diambil dan aplikasi sedang digunakan."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"kirimkan perintah ke SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Mengizinkan aplikasi mengirim perintah ke SIM. Ini sangat berbahaya."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"kenali aktivitas fisik"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera ponsel dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Konten ini tidak dapat diakses saat melakukan streaming. Coba di ponsel."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Tidak dapat menampilkan picture-in-picture saat streaming"</string> <string name="system_locale_title" msgid="711882686834677268">"Default sistem"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTU <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 919276e23272..a97ac9849902 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Leyfir forriti að gera hluta sjálfs sín varanlega í minni. Þetta getur takmarkað það minni sem býðst öðrum forritum og þannig hægt á símanum."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"keyra þjónustu í forgrunni"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Leyfir forritinu að nota þjónustu sem er í forgrunni."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"keyra forgrunnsþjónustu af gerðinni „camera“"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „camera“"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"keyra forgrunnsþjónustu af gerðinni „connectedDevice“"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „connectedDevice“"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"keyra forgrunnsþjónustu af gerðinni „dataSync“"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „dataSync“"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"keyra forgrunnsþjónustu af gerðinni „location“"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „location“"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"keyra forgrunnsþjónustu af gerðinni „mediaPlayback“"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „mediaPlayback“"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"keyra forgrunnsþjónustu af gerðinni „mediaProjection“"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „mediaProjection“"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"keyra forgrunnsþjónustu af gerðinni „microphone“"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „microphone“"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"keyra forgrunnsþjónustu af gerðinni „phoneCall“"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „phoneCall“"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"keyra forgrunnsþjónustu af gerðinni „health“"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „health“"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"keyra forgrunnsþjónustu af gerðinni „remoteMessaging“"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „remoteMessaging“"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"keyra forgrunnsþjónustu af gerðinni „systemExempted“"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „systemExempted“"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"keyra forgrunnsþjónustu af gerðinni „specialUse“"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Leyfir forritinu að nota forgrunnsþjónustu af gerðinni „specialUse“"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"mæla geymslurými forrits"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Leyfir forriti að sækja stærðir kóða, gagna og skyndiminnis síns."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"breyta kerfisstillingum"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Þetta forrit getur tekið upp hljóð með hljóðnemanum meðan forritið er í notkun."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"taka upp hljóð í bakgrunni"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Þetta forrit getur tekið upp hljóð með hljóðnemanum hvenær sem er."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"greina skjáupptöku í forritagluggum"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Tilkynning berst til forritsins þegar skjámynd er tekin á meðan forritið er í notkun."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"senda skipanir til SIM-kortsins"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Leyfir forriti að senda SIM-kortinu skipanir. Þetta er mjög hættulegt."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"greina hreyfingu"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ekki er hægt að opna myndavél símans úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ekki er hægt að opna myndavél spjaldtölvunnar úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Ekki er hægt að opna þetta á meðan streymi stendur yfir. Prófaðu það í símanum í staðinn."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Ekki er hægt að horfa á mynd í mynd á meðan streymi er í gangi"</string> <string name="system_locale_title" msgid="711882686834677268">"Sjálfgildi kerfis"</string> <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index beb15d229a66..e27538a05750 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Consente all\'applicazione di rendere persistenti in memoria alcune sue parti. Ciò può limitare la memoria disponibile per altre applicazioni, rallentando il telefono."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"esecuzione servizio in primo piano"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Consente all\'app di utilizzare i servizi in primo piano."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"Esecuzione di servizi in primo piano con il tipo \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Consente all\'app di usare i servizi in primo piano con il tipo \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"Esecuzione di servizi in primo piano con il tipo \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Consente all\'app di usare i servizi in primo piano con il tipo \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"Esecuzione di servizi in primo piano con il tipo \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Consente all\'app di usare i servizi in primo piano con il tipo \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"Esecuzione di servizi in primo piano con il tipo \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Consente all\'app di usare i servizi in primo piano con il tipo \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"Esecuzione di servizi in primo piano con il tipo \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Consente all\'app di usare i servizi in primo piano con il tipo \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"Esecuzione di servizi in primo piano con il tipo \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Consente all\'app di usare i servizi in primo piano con il tipo \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"Esecuzione di servizi in primo piano con il tipo \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Consente all\'app di usare i servizi in primo piano con il tipo \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"Esecuzione di servizi in primo piano con il tipo \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Consente all\'app di usare i servizi in primo piano con il tipo \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"Esecuzione di servizi in primo piano con il tipo \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Consente all\'app di usare i servizi in primo piano con il tipo \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"Esecuzione di servizi in primo piano con il tipo \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Consente all\'app di usare i servizi in primo piano con il tipo \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"Esecuzione di servizi in primo piano con il tipo \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Consente all\'app di usare i servizi in primo piano con il tipo \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"Esecuzione di servizi in primo piano con il tipo \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Consente all\'app di usare i servizi in primo piano con il tipo \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"calcolo spazio di archiviazione applicazioni"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Consente all\'applicazione di recuperare il suo codice, i suoi dati e le dimensioni della cache"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modifica delle impostazioni di sistema"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Questa app può registrare audio tramite il microfono mentre l\'app è in uso."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Registrazione di audio in background"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Questa app può registrare audio tramite il microfono in qualsiasi momento."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"rileva le acquisizioni schermo delle finestre dell\'app"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Questa app riceverà una notifica quando viene acquisito uno screenshot mentre è in uso."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"invio di comandi alla SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Consente all\'app di inviare comandi alla SIM. Questo è molto pericoloso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"riconoscimento dell\'attività fisica"</string> @@ -2013,7 +1987,7 @@ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Questa app richiede maggiore sicurezza. Prova a usare il telefono."</string> <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Non è possibile accedere a questa impostazione su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il dispositivo Android TV."</string> <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Non è possibile accedere a questa impostazione su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il tablet."</string> - <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non è possibile accedere a questa impostazione su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string> + <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non è possibile accedere su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string> <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Questa app è stata progettata per una versione precedente di Android. Potrebbe non funzionare correttamente e non include le protezioni della sicurezza e della privacy più recenti. Verifica la presenza di un aggiornamento o contatta lo sviluppatore dell\'app."</string> <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca aggiornamenti"</string> <string name="new_sms_notification_title" msgid="6528758221319927107">"Hai nuovi messaggi"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossibile accedere alla fotocamera del telefono dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossibile accedere alla fotocamera del tablet dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Impossibile accedere a questi contenuti durante lo streaming. Prova a usare il telefono."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Impossibile visualizzare Picture in picture durante lo streaming"</string> <string name="system_locale_title" msgid="711882686834677268">"Predefinita di sistema"</string> <string name="default_card_name" msgid="9198284935962911468">"SCHEDA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 34f4bee4a575..a074860db006 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"מאפשרת לאפליקציה להפוך חלקים ממנה לקבועים בזיכרון. הפעולה הזו עשויה להגביל את הזיכרון הזמין לאפליקציות אחרות ולהאט את פעולת הטלפון."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"הפעלת שירות בחזית"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"הפעלת שירות שפועל בחזית מסוג \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"הפעלת שירות שפועל בחזית מסוג \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"הפעלת שירות שפועל בחזית מסוג \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"הפעלת שירות שפועל בחזית מסוג \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"הפעלת שירות שפועל בחזית מסוג \'mediaPlayback\'"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"הפעלת שירות שפועל בחזית מסוג \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"הפעלת שירות שפועל בחזית מסוג \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"הפעלת שירות שפועל בחזית מסוג \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"הפעלת שירות שפועל בחזית מסוג \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"הפעלת שירות שפועל בחזית מסוג \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"הפעלת שירות שפועל בחזית מסוג \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"הפעלת שירות שפועל בחזית מסוג \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"ההרשאה הזו מאפשרת לאפליקציה להשתמש בשירותים שפועלים בחזית מסוג \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"מדידת נפח האחסון של אפליקציות"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"מאפשרת לאפליקציה לאחזר את הקוד, הנתונים, ואת גודל קובצי המטמון שלה"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"שינוי הגדרות מערכת"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"האפליקציה הזו יכולה להשתמש במיקרופון כדי להקליט אודיו כאשר היא בשימוש."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"הקלטת אודיו ברקע"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"האפליקציה הזו יכולה להשתמש במיקרופון כדי להקליט אודיו בכל זמן."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"זיהוי צילומי מסך של חלונות האפליקציה"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"לאפליקציה הזו תישלח התראה אם יצולם צילום מסך בזמן שהיא בשימוש."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"שליחת פקודות אל ה-SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"מאפשרת לאפליקציה לשלוח פקודות ל-SIM. זוהי הרשאה מסוכנת מאוד."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"זיהוי של פעילות גופנית"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index da7e3872b2e2..140ba8857874 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"アプリにその一部をメモリに常駐させることを許可します。これにより他のアプリが使用できるメモリが制限されるため、モバイル デバイスの動作が遅くなることがあります。"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"フォアグラウンド サービスの実行"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"フォアグラウンド サービスの使用をアプリに許可します。"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"タイプが「camera」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"タイプが「camera」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"タイプが「connectedDevice」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"タイプが「connectedDevice」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"タイプが「dataSync」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"タイプが「dataSync」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"タイプが「location」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"タイプが「location」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"タイプが「mediaPlayback」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"タイプが「mediaPlayback」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"タイプが「mediaProjection」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"タイプが「mediaProjection」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"タイプが「microphone」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"タイプが「microphone」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"タイプが「phoneCall」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"タイプが「phoneCall」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"タイプが「health」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"タイプが「health」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"タイプが「remoteMessaging」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"タイプが「remoteMessaging」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"タイプが「systemExempted」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"タイプが「systemExempted」のフォアグラウンド サービスの使用をアプリに許可します"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"タイプが「specialUse」のフォアグラウンド サービスの実行"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"タイプが「specialUse」のフォアグラウンド サービスの使用をアプリに許可します"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"アプリのストレージ容量の計測"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"アプリのコード、データ、キャッシュサイズを取得することをアプリに許可します"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"システム設定の変更"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 664a25cc7d7a..a5371d215b3b 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"აპს შეეძლება, საკუთარი ნაწილები მუდმივად ჩაწეროს მეხსიერებაში. ეს შეზღუდავს მეხსიერების ხელმისაწვდომობას სხვა აპებისთვის და შეანელებს ტელეფონს."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"წინა პლანის სერვისის გაშვება"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"აპს შეეძლება, გამოიყენოს წინა პლანის სერვისები."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"პრიორიტეტული სერვისის გაშვება ტიპის „კამერა“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „კამერა“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"პრიორიტეტული სერვისის გაშვება ტიპის „დაკავშირებულიმოწყობილობა“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „დაკავშირებულიმოწყობილობა“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"პრიორიტეტული სერვისის გაშვება ტიპის „მონაცემებისსინქრონიზაცია“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „მონაცემებისსინქრონიზაცია“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"პრიორიტეტული სერვისის გაშვება ტიპის „მდებარეობა“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „მდებარეობა“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"პრიორიტეტული სერვისის გაშვება ტიპის „მედია-ფაილებისდაკვრა“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „მედია-ფაილებისდაკვრა“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"პრიორიტეტული სერვისის გაშვება ტიპის „მედიაპროეცირება“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „მედიაპროეცირება“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"პრიორიტეტული სერვისის გაშვება ტიპის „მიკროფონი“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „მიკროფონი“ შემთხვევაში"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"პრიორიტეტული სერვისის გაშვება ტიპის „სატელეფონოზარი“ შემთხვევაში"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „სატელეფონოზარი“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"პრიორიტეტული სერვისის გაშვება ტიპის „ჯანმრთელობა“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „ჯანმრთელობა“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"პრიორიტეტული სერვისის გაშვება ტიპის „დისტანციურიშეტყობინებები“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „დისტანციურიშეტყობინებები“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"პრიორიტეტული სერვისის გაშვება ტიპის \"გათავისუფლებულისისტემა\" შემთხვევაში"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „გათავისუფლებულისისტემა“ შემთხვევაში"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"პრიორიტეტული სერვისის გაშვება ტიპის „სპეციალურიგამოყენება“ შემთხვევაში"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"ნებას რთავს აპს, გამოიყენოს პრიორიტეტული სერვისები ტიპის „სპეციალურიგამოყენება“ შემთხვევაში"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"აპის მეხსიერების სივრცის გაზომვა"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"აპს შეეძლება, მოიპოვოს თავისი კოდი, მონაცემები და ქეშის ზომები."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"სისტემის პარამეტრების შეცვლა"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ტელეფონის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ტაბლეტის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string> <string name="vdm_secure_window" msgid="161700398158812314">"მასზე წვდომის მიᲦება შეუძლებელია სტრიმინგის დროს. ცადეთ ტელეფონიდან."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"სტრიმინგის დროს ეკრანის ეკრანში ნახვა შეუძლებელია"</string> <string name="system_locale_title" msgid="711882686834677268">"სისტემის ნაგულისხმევი"</string> <string name="default_card_name" msgid="9198284935962911468">"ბარათი <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 14da390c57c0..47afaa301602 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -495,10 +495,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Бұл қолданба жұмыс барысында микрофон арқылы аудиомазмұн жаза алады."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Фондық режимде аудиомазмұн жазу"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Бұл қолданба кез келген уақытта микрофон арқылы аудиомазмұн жаза алады."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"қолданба терезелерінің скриншоттарын анықтау"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Қолданбаны пайдаланып скриншот жасаған кезде, ескерту шығады."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM картасына пәрмендер жіберу"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Қолданбаға SIM картасына пәрмен жіберу мүмкіндігін береді. Бұл өте қауіпті."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"физикалық әрекетті тану"</string> @@ -2342,8 +2340,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан телефон камерасын пайдалану мүмкін емес."</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан планшет камерасын пайдалану мүмкін емес."</string> <string name="vdm_secure_window" msgid="161700398158812314">"Трансляция кезінде мазмұнды көру мүмкін емес. Оның орнына телефоннан көріңіз."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Трансляция кезінде суреттегі суретті көру мүмкін емес."</string> <string name="system_locale_title" msgid="711882686834677268">"Жүйенің әдепкі параметрі"</string> <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g>-КАРТА"</string> </resources> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index fc1a49c7e56e..3f0ae1fa76cf 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"ឲ្យកម្មវិធី ធ្វើជាផ្នែកអចិន្ត្រៃយ៍នៃខ្លួនក្នុងអង្គចងចាំ។ វាអាចកម្រិតអង្គចងចាំអាចប្រើបាន ដើម្បីធ្វើឲ្យកម្មវិធីផ្សេងធ្វើឲ្យទូរស័ព្ទរបស់អ្នកយឺត។"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខ"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខ។"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"ដំណើរការសេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"អនុញ្ញាតឱ្យកម្មវិធីប្រើប្រាស់សេវាកម្មផ្ទៃខាងមុខជាមួយនឹងប្រភេទ \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"វាស់ទំហំការផ្ទុកកម្មវិធី"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"ឲ្យកម្មវិធីទៅយកកូដ ទិន្នន័យ និងទំហំឃ្លាំងសម្ងាត់របស់វា"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"កែការកំណត់ប្រព័ន្ធ"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"កម្មវិធីនេះអាចថតសំឡេងដោយប្រើមីក្រូហ្វូន នៅពេលកំពុងប្រើប្រាស់កម្មវិធី។"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ថតសំឡេងនៅផ្ទៃខាងក្រោយ"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"កម្មវិធីនេះអាចថតសំឡេងដោយប្រើមីក្រូហ្វូនបានគ្រប់ពេល។"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"រកឃើញការថតអេក្រង់វិនដូកម្មវិធី"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"កម្មវិធីនេះនឹងទទួលបានការជូនដំណឹងនៅពេលរូបថតអេក្រង់ត្រូវបានថត ខណៈពេលកំពុងប្រើកម្មវិធីនេះ។"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"ផ្ញើពាក្យបញ្ជាទៅស៊ីមកាត"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"ឲ្យកម្មវិធីផ្ញើពាក្យបញ្ជាទៅស៊ីមកាត។ វាគ្រោះថ្នាក់ណាស់។"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ស្គាល់សកម្មភាពរាងកាយ"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"មិនអាចចូលប្រើកាមេរ៉ាទូរសព្ទពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកបានទេ"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"មិនអាចចូលប្រើកាមេរ៉ាថេប្លេតពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកបានទេ"</string> <string name="vdm_secure_window" msgid="161700398158812314">"មិនអាចចូលប្រើប្រាស់ខ្លឹមសារនេះបានទេ ពេលផ្សាយ។ សូមសាកល្បងប្រើនៅលើទូរសព្ទរបស់អ្នកជំនួសវិញ។"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"មិនអាចមើលរូបក្នុងរូបខណៈពេលកំពុងផ្សាយបានទេ"</string> <string name="system_locale_title" msgid="711882686834677268">"លំនាំដើមប្រព័ន្ធ"</string> <string name="default_card_name" msgid="9198284935962911468">"កាត <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 7ca2dfffc494..2a550defcb0d 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"ಸ್ಮರಣೆಯಲ್ಲಿ ನಿರಂತರವಾಗಿ ತನ್ನದೇ ಭಾಗಗಳನ್ನು ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದು ಫೋನ್ ಕಾರ್ಯವನ್ನು ನಿಧಾನಗೊಳಿಸುವುದರ ಮೂಲಕ ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಲಭ್ಯವಿರುವ ಸ್ಮರಣೆಯನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡಿ."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"ಕ್ಯಾಮರಾ\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"\"ಕ್ಯಾಮರಾ\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"\"connectedDevice\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"\"dataSync\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"ಸ್ಥಳ\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"\"ಸ್ಥಳ\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"\"mediaPlayback\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"\"mediaProjection\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"ಮೈಕ್ರೊಫೋನ್\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"\"ಮೈಕ್ರೊಫೋನ್\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"\"phoneCall\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"ಅರೋಗ್ಯ\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"\"ಅರೋಗ್ಯ\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"\"remoteMessaging\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"\"systemExempted\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಯನ್ನು ರನ್ ಮಾಡಿ"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"\"specialUse\" ಪ್ರಕಾರದೊಂದಿಗೆ ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ಅಪ್ಲಿಕೇಶನ್ ಸಂಗ್ರಹ ಸ್ಥಳವನ್ನು ಅಳೆಯಿರಿ"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"ಅದರ ಕೋಡ್, ಡೇಟಾ, ಮತ್ತು ಕ್ಯಾಷ್ ಗಾತ್ರಗಳನ್ನು ಹಿಂಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ಸಿಸ್ಟಂ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಿ"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಈ ಆ್ಯಪ್ ಮೈಕ್ರೊಫೋನ್ ಬಳಸಿ ಆಡಿಯೊವನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಆಡಿಯೊವನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"ಈ ಆ್ಯಪ್ ಮೈಕ್ರೋಫೋನ್ ಬಳಸುವ ಮೂಲಕ ಯಾವುದೇ ಸಮಯದಲ್ಲಾದರೂ ಆಡಿಯೋ ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ಆ್ಯಪ್ ವಿಂಡೋಗಳ ಸ್ಕ್ರೀನ್ ಕ್ಯಾಪ್ಚರ್ಗಳನ್ನು ಪತ್ತೆ ಮಾಡಿ"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಒಂದನ್ನು ತೆಗೆದುಕೊಂಡಾಗ ಈ ಆ್ಯಪ್ ಸೂಚನೆಯನ್ನು ಪಡೆಯುತ್ತದೆ."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"ಸಿಮ್ಗೆ ಆಜ್ಞೆಗಳನ್ನು ಕಳುಹಿಸಿ"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"ಸಿಮ್ ಗೆ ಆದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ತುಂಬಾ ಅಪಾಯಕಾರಿ."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ದೈಹಿಕ ಚಟುವಟಿಕೆಯನ್ನು ಗುರುತಿಸಿ"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಫೋನ್ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಟ್ಯಾಬ್ಲೆಟ್ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ಸ್ಟ್ರೀಮ್ ಮಾಡುವಾಗ ಇದನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಬದಲು ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"ಸ್ಟ್ರೀಮ್ ಮಾಡುವಾಗ ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವನ್ನು ವೀಕ್ಷಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="system_locale_title" msgid="711882686834677268">"ಸಿಸ್ಟಂ ಡೀಫಾಲ್ಟ್"</string> <string name="default_card_name" msgid="9198284935962911468">"ಕಾರ್ಡ್ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index a3a2f22e17a9..f55dfab9f3f7 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"앱이 그 일부분을 영구적인 메모리로 만들 수 있도록 허용합니다. 이렇게 하면 다른 앱이 사용할 수 있는 메모리를 제한하여 휴대전화의 속도를 저하시킬 수 있습니다."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"포그라운드 서비스 실행"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"앱에서 포그라운드 서비스를 사용하도록 허용합니다."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\'camera\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"앱에서 \'camera\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\'connectedDevice\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"앱에서 \'connectedDevice\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\'dataSync\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"앱에서 \'dataSync\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\'location\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"앱에서 \'location\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\'mediaPlayback\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"앱에서 \'mediaPlayback\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\'mediaProjection\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"앱에서 \'mediaProjection\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\'microphone\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"앱에서 \'microphone\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\'phoneCall\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"앱에서 \'phoneCall\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\'health\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"앱에서 \'health\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\'remoteMessaging\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"앱에서 \'remoteMessaging\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\'systemExempted\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"앱에서 \'systemExempted\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\'specialUse\' 유형의 포그라운드 서비스 실행"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"앱에서 \'specialUse\' 유형의 포그라운드 서비스를 사용하도록 허용합니다."</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"앱 저장공간 계산"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"앱이 해당 코드, 데이터 및 캐시 크기를 검색할 수 있도록 허용합니다."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"시스템 설정 수정"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"앱을 사용하는 동안 앱에서 마이크를 사용하여 오디오를 녹음할 수 있습니다."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"백그라운드에서 오디오 녹음"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"언제든지 앱에서 마이크를 사용하여 오디오를 녹음할 수 있습니다."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"앱 창 화면 캡처 감지"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"앱이 사용 중일 때 스크린샷을 찍으면 알림이 전송됩니다."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM 카드로 명령 전송"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"앱이 SIM에 명령어를 전송할 수 있도록 허용합니다. 이 기능은 매우 신중히 허용해야 합니다."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"신체 활동 확인"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 휴대전화 카메라에 액세스할 수 없습니다."</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 태블릿 카메라에 액세스할 수 없습니다."</string> <string name="vdm_secure_window" msgid="161700398158812314">"스트리밍 중에는 액세스할 수 없습니다. 대신 휴대전화에서 시도해 보세요."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"스트리밍 중에는 PIP 모드를 볼 수 없습니다."</string> <string name="system_locale_title" msgid="711882686834677268">"시스템 기본값"</string> <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g> 카드"</string> </resources> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 92943d0bd148..26e5c1e4bf86 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Колдонмого өзүнүн бөлүктөрүн эстутумда туруктуу кармоого уруксат берет. Бул эстутумдун башка колдонмолорго жетиштүүлүгүн чектеши жана телефондун иштешин жайлатышы мүмкүн."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"активдүү кызматты иштетүү"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Колдонмолорго алдынкы пландагы кызматтарды колдонууга уруксат берет."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"алдынкы пландагы \"camera\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Колдонмолорго алдынкы пландагы \"camera\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"алдынкы пландагы \"connectedDevice\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Колдонмолорго алдынкы пландагы \"connectedDevice\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"алдынкы пландагы \"dataSync\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Колдонмолорго алдынкы пландагы \"dataSync\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"алдынкы пландагы \"location\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Колдонмолорго алдынкы пландагы \"location\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"алдынкы пландагы \"mediaPlayback\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Колдонмолорго алдынкы пландагы \"mediaPlayback\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"алдынкы пландагы \"mediaProjection\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Колдонмолорго алдынкы пландагы \"mediaProjection\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"алдынкы пландагы \"microphone\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Колдонмолорго алдынкы пландагы \"microphone\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"алдынкы пландагы \"phoneCall\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Колдонмолорго алдынкы пландагы \"phoneCall\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"алдынкы пландагы \"health\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Колдонмолорго алдынкы пландагы \"health\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"алдынкы пландагы \"remoteMessaging\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Колдонмолорго алдынкы пландагы \"remoteMessaging\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"алдынкы пландагы \"systemExempted\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Колдонмолорго алдынкы пландагы \"systemExempted\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"алдынкы пландагы \"specialUse\" түрүндөгү кызматты аткаруу"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Колдонмолорго алдынкы пландагы \"specialUse\" түрүндөгү кызматтарды колдонууга уруксат берет"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"колдонмо сактагычынын мейкиндигин өлчөө"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Колдонмого өз кодун, дайындарын жана кэш өлчөмдөрүн түшүрүп алуу мүмкүнчүлүгүн берет"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"система тууралоолорун өзгөртүү"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Бул колдонмо иштеп жатканда микрофон менен аудио файлдарды жаздыра алат."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Фондо аудио жаздыруу"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Бул колдонмо каалаган убакта микрофон менен аудио файлдарды жаздыра алат."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"колдонмонун терезелериндегилер сүрөткө тартылганын аныктоо"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Колдонмо иштеп жатканда скриншот тартылса, колдонмого кабарланат."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM-картага буйруктарды жөнөтүү"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Колдонмого SIM-картага буйруктарды жөнөтүү мүмкүнчүлүгүн берет. Бул абдан кооптуу."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"Кыймыл-аракетти аныктоо"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн телефондун камерасына мүмкүнчүлүк жок"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн планшетиңиздин камерасына мүмкүнчүлүк жок"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Муну алып ойнотуу учурунда көрүүгө болбойт. Анын ордуна телефондон кирип көрүңүз."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Алып ойнотуп жатканда сүрөттөгү сүрөт көрүнбөйт"</string> <string name="system_locale_title" msgid="711882686834677268">"Системанын демейки параметрлери"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 0f73d6864416..4b8e82b06fcf 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"ອະນຸຍາດໃຫ້ແອັບຯເຮັດໃຫ້ສ່ວນນຶ່ງຂອງຕົນເອງ ຄົງຢູ່ຖາວອນໃນໜ່ວຍຄວາມຈຳ ເຊິ່ງອາດສາມາດ ເຮັດໃຫ້ການນຳໃຊ້ໜ່ວຍຄວາມຈຳຂອງແອັບຯ ອື່ນຖືກຈຳກັດ ສົ່ງຜົນເຮັດໃຫ້ມືຖືຂອງທ່ານເຮັດວຽກຊ້າລົງໄດ້."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ໃຊ້ບໍລິການພື້ນໜ້າ"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ບໍລິການພື້ນໜ້າ."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ກ້ອງຖ່າຍຮູບ\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ກ້ອງຖ່າຍຮູບ\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ອຸປະກອນທີ່ເຊື່ອມຕໍ່\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ອຸປະກອນທີ່ເຊື່ອມຕໍ່\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການຊິ້ງຂໍ້ມູນ\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການຊິ້ງຂໍ້ມູນ\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ສະຖານທີ່\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ສະຖານທີ່\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການຫຼິ້ນມີເດຍ\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການຫຼິ້ນມີເດຍ\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການສາຍພາບມີເດຍ\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການສາຍພາບມີເດຍ\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ໄມໂຄຣໂຟນ\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ໄມໂຄຣໂຟນ\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ສາຍໂທ\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ສາຍໂທ\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ສຸຂະພາບ\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ສຸຂະພາບ\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການຮັບສົ່ງຂໍ້ຄວາມຈາກໄລຍະໄກ\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການຮັບສົ່ງຂໍ້ຄວາມຈາກໄລຍະໄກ\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ໄດ້ຮັບການຍົກເວັ້ນຈາກລະບົບ\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ໄດ້ຮັບການຍົກເວັ້ນຈາກລະບົບ\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"ເອີ້ນໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການນຳໃຊ້ພິເສດ\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ປະໂຫຍດຈາກບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າໂດຍມີປະເພດເປັນ \"ການນຳໃຊ້ພິເສດ\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ກວດສອບພື້ນທີ່ຈັດເກັບຂໍ້ມູນແອັບຯ"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"ອະນຸຍາດໃຫ້ແອັບຯດຶງໂຄດ, ຂໍ້ມູນ ແລະຂະໜາດ cache ຂອງມັນໄດ້."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ແກ້ໄຂການຕັ້ງຄ່າລະບົບ"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ແອັບນີ້ສາມາດບັນທຶກສຽງດ້ວຍໄມໂຄຣໂຟນໃນຂະນະທີ່ກຳລັງໃຊ້ແອັບຢູ່ໄດ້."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ບັນທຶກສຽງໃນພື້ນຫຼັງ"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"ແອັບນີ້ສາມາດບັນທຶກສຽງດ້ວຍໄມໂຄຣໂຟນຕອນໃດກໍໄດ້."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ກວດຫາການຖ່າຍຮູບໜ້າຈໍຂອງໜ້າຈໍແອັບ"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"ແອັບນີ້ຈະໄດ້ຮັບການແຈ້ງເຕືອນເມື່ອມີການຖ່າຍຮູບໜ້າຈໍໃນຂະນະທີ່ກຳລັງໃຊ້ແອັບຢູ່."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"ສົ່ງຄຳສັ່ງຫາ SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງຄຳສັ່ງຫາ SIM. ສິ່ງນີ້ອັນຕະລາຍຫຼາຍ."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ຈຳແນກກິດຈະກຳທາງກາຍ"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງໂທລະສັບຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງແທັບເລັດຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ບໍ່ສາມາດເຂົ້າເຖິງເນື້ອຫານີ້ໄດ້ໃນຂະນະທີ່ຍັງສະຕຣີມຢູ່. ກະລຸນາລອງຢູ່ໂທລະສັບຂອງທ່ານແທນ."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"ບໍ່ສາມາດເບິ່ງການສະແດງຜົນຊ້ອນກັນໃນຂະນະທີ່ສະຕຣີມໄດ້"</string> <string name="system_locale_title" msgid="711882686834677268">"ຄ່າເລີ່ມຕົ້ນຂອງລະບົບ"</string> <string name="default_card_name" msgid="9198284935962911468">"ບັດ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 404dbd8f7ca7..341612c1b724 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Leidžiama programai savo dalis įrašyti į atmintį. Dėl to gali būti apribota kitomis programomis pasiekiama atmintis ir sulėtėti telefono veikimas."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"vykdyti priekiniame plane veikiančią paslaugą"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Programai leidžiama naudoti priekiniame plane veikiančias paslaugas."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"paleisti priekinio plano paslaugą, kurios tipas „camera“"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „camera“"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"paleisti priekinio plano paslaugą, kurios tipas „connectedDevice“"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „connectedDevice“"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"paleisti priekinio plano paslaugą, kurios tipas „dataSync“"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „dataSync“"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"paleisti priekinio plano paslaugą, kurios tipas „location“"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „location“"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"paleisti priekinio plano paslaugą, kurios tipas „mediaPlayback“"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „mediaPlayback“"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"paleisti priekinio plano paslaugą, kurios tipas „mediaProjection“"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „mediaProjection“"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"paleisti priekinio plano paslaugą, kurios tipas „microphone“"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „microphone“"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"paleisti priekinio plano paslaugą, kurios tipas „phoneCall“"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „phoneCall“"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"paleisti priekinio plano paslaugą, kurios tipas „health“"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „health“"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"paleisti priekinio plano paslaugą, kurios tipas „remoteMessaging“"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „remoteMessaging“"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"paleisti priekinio plano paslaugą, kurios tipas „systemExempted“"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „systemExempted“"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"paleisti priekinio plano paslaugą, kurios tipas „specialUse“"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Programai leidžiama naudoti priekinio plano paslaugas, kurių tipas „specialUse“"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"matuoti programos atmintinės vietą"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Leidžiama programai nuskaityti kodą, duomenis ir talpykloje saugoti dydžius"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"keisti sistemos nustatymus"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ši programa gali įrašyti garsą naudodama mikrofoną, kol programa naudojama."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"įrašyti garsą fone"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ši programa gali bet kada įrašyti garsą naudodama mikrofoną."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"Programos langų ekrano fiksavimo aptikimas"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Šiai programai bus pranešta, kai bus sukurta ekrano kopija, kol programa naudojama."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"siųsti komandas į SIM kortelę"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Programai leidžiama siųsti komandas į SIM kortelę. Tai labai pavojinga."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"atpažinti fizinę veiklą"</string> @@ -2344,8 +2318,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nepavyko pasiekti telefono fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nepavyko pasiekti planšetinio kompiuterio fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Nepavyksta pasiekti perduodant srautu. Pabandykite naudoti telefoną."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Negalima peržiūrėti vaizdo vaizde perduodant srautu"</string> <string name="system_locale_title" msgid="711882686834677268">"Numatytoji sistemos vertė"</string> <string name="default_card_name" msgid="9198284935962911468">"KORTELĖ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 721c17ea1be8..b57de7772e45 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Ļauj lietotnei nodrošināt atsevišķu tās daļu nepārtrauktu atrašanos atmiņā. Tas var ierobežot pieejamo atmiņas daudzumu citām lietotnēm, tādējādi palēninot tālruņa darbību."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"Aktivizēt priekšplāna pakalpojumu"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Ļauj lietotnei izmantot priekšplāna pakalpojumus."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"izpildīt šāda veida priekšplāna pakalpojumu: camera"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: camera"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"izpildīt šāda veida priekšplāna pakalpojumu: connectedDevice"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: connectedDevice"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"izpildīt šāda veida priekšplāna pakalpojumu: dataSync"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: dataSync"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"izpildīt šāda veida priekšplāna pakalpojumu: location"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: location"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"izpildīt šāda veida priekšplāna pakalpojumu: mediaPlayback"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: mediaPlayback"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"izpildīt šāda veida priekšplāna pakalpojumu: mediaProjection"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: mediaProjection"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"izpildīt šāda veida priekšplāna pakalpojumu: microphone"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: microphone"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"izpildīt šāda veida priekšplāna pakalpojumu: phoneCall"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: phoneCall"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"izpildīt šāda veida priekšplāna pakalpojumu: health"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: health"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"izpildīt šāda veida priekšplāna pakalpojumu: remoteMessaging"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: remoteMessaging"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"izpildīt šāda veida priekšplāna pakalpojumu: systemExempted"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: systemExempted"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"izpildīt šāda veida priekšplāna pakalpojumu: specialUse"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Ļauj lietotnei izmantot šāda veida priekšplāna pakalpojumus: specialUse"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"noteikt vietas apjomu lietotnes atmiņā"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Ļauj lietotnei izgūt tās koda datus un kešatmiņas izmēru."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"mainīt sistēmas iestatījumus"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Šī lietotne var ierakstīt audio, izmantojot mikrofonu, kamēr lietotne tiek izmantota."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ierakstīt audio fonā"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Šī lietotne var jebkurā brīdī ierakstīt audio, izmantojot mikrofonu."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"noteikt lietotnes logu ekrānuzņēmumu izveidi"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ja lietotnes izmantošanas laikā tiks izveidots ekrānuzņēmums, lietotnei tiks nosūtīts paziņojums."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"Sūtīt komandas SIM kartei"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Ļauj lietotnei sūtīt komandas uz SIM karti. Tas ir ļoti bīstami!"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"noteikt fiziskās aktivitātes"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nevar piekļūt tālruņa kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nevar piekļūt planšetdatora kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string> <string name="vdm_secure_window" msgid="161700398158812314">"Straumēšanas laikā nevar piekļūt šim saturam. Mēģiniet tam piekļūt savā tālrunī."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Straumēšanas laikā nevar skatīt attēlu attēlā"</string> <string name="system_locale_title" msgid="711882686834677268">"Sistēmas noklusējums"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index b3d46dbc99ea..51a6055ebab5 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Овозможува апликацијата да прави трајни делови од себеси во меморијата. Ова може да ја ограничи расположливата меморија на други апликации што го забавува телефонот."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"извршување услуга во преден план"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Дозволува апликацијата да ги користи услугите во преден план."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"да извршува во преден план услуга со типот „camera“"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Дозволува апликацијата да ги користи во преден план услугите со типот „camera“"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"да извршува во преден план услуга со типот „connectedDevice“"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Дозволува апликацијата да ги користи во преден план услугите со типот „connectedDevice“"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"да извршува во преден план услуга со типот „dataSync“"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Дозволува апликацијата да ги користи во преден план услугите со типот „dataSync“"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"да извршува во преден план услуга со типот „location“"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Дозволува апликацијата да ги користи во преден план услугите со типот „location“"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"да извршува во преден план услуга со типот „mediaPlayback“"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Дозволува апликацијата да ги користи во преден план услугите со типот „mediaPlayback“"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"да извршува во преден план услуга со типот „mediaProjection“"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Дозволува апликацијата да ги користи во преден план услугите со типот „mediaProjection“"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"да извршува во преден план услуга со типот „microphone“"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Дозволува апликацијата да ги користи во преден план услугите со типот „microphone“"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"да извршува во преден план услуга со типот „phoneCall“"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Дозволува апликацијата да ги користи во преден план услугите со типот „phoneCall“"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"да извршува во преден план услуга со типот „health“"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Дозволува апликацијата да ги користи во преден план услугите со типот „health“"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"да извршува во преден план услуга со типот „remoteMessaging“"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Дозволува апликацијата да ги користи во преден план услугите со типот „remoteMessaging“"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"да извршува во преден план услуга со типот „systemExempted“"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Дозволува апликацијата да ги користи во преден план услугите со типот „systemExempted“"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"да извршува во преден план услуга со типот „specialUse“"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Дозволува апликацијата да ги користи во преден план услугите со типот „specialUse“"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"измери простор за складирање на апликацијата"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Дозволува апликацијата да ги обнови кодот, податоците и величините на кеш."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"менува системски поставки"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се пристапи до камерата на вашиот телефон од <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се пристапи до камерата на вашиот таблет од <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"До ова не може да се пристапи при стриминг. Наместо тоа, пробајте на вашиот телефон."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Не може да се прикажува слика во слика при стримување"</string> <string name="system_locale_title" msgid="711882686834677268">"Стандардно за системот"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТИЧКА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index efc475c71b41..1b9fc946422a 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"മെമ്മറിയിൽ അപ്ലിക്കേഷനുകളുടെ ഭാഗങ്ങൾ നിലനിർത്താൻ സ്വയം അനുവദിക്കുന്നു. ഇത് ഫോണിനെ മന്ദഗതിയിലാക്കുന്ന വിധത്തിൽ മറ്റ് അപ്ലിക്കേഷനുകൾക്ക് ലഭ്യമായ മെമ്മറി പരിമിതപ്പെടുത്താനിടയുണ്ട്."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"മുൻവശത്തുള്ള സേവനം റൺ ചെയ്യുക"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"മുൻവശത്തുള്ള സേവനങ്ങൾ ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"\"camera\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"\"connectedDevice\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"\"dataSync\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"\"location\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"\"mediaPlayback\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"\"mediaProjection\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"\"microphone\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"\"phoneCall\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"\"health\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"\"remoteMessaging\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"\"systemExempted\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനം റൺ ചെയ്യുക"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"\"specialUse\" എന്ന തരം ഉപയോഗിച്ച് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ പ്രയോജനപ്പെടുത്താൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"അപ്ലിക്കേഷൻ സംഭരണയിടം അളക്കുക"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"അപ്ലിക്കേഷന്റെ കോഡ്, ഡാറ്റ, കാഷെ വലുപ്പങ്ങൾ എന്നിവ വീണ്ടെടുക്കുന്നതിന് അതിനെ അനുവദിക്കുക"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"സിസ്റ്റം ക്രമീകരണങ്ങൾ പരിഷ്ക്കരിക്കുക"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ആപ്പ് ഉപയോഗത്തിലായിരിക്കുമ്പോൾ മൈക്രോഫോൺ ഉപയോഗിച്ച് ഓഡിയോ റെക്കോർഡ് ചെയ്യാൻ ഈ ആപ്പിന് കഴിയും."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"പശ്ചാത്തലത്തിൽ ഓഡിയോ റെക്കോർഡ് ചെയ്യുക"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"ഈ ആപ്പിന് ഏത് സമയത്തും മൈക്രോഫോൺ ഉപയോഗിച്ച് ഓഡിയോ റെക്കോർഡ് ചെയ്യാൻ കഴിയും."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ആപ്പ് വിൻഡോകളുടെ സ്ക്രീൻ ക്യാപ്ചർ ചെയ്യലുകൾ കണ്ടെത്തുക"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"ആപ്പ് ഉപയോഗിച്ചുകൊണ്ടിരിക്കുമ്പോൾ സ്ക്രീൻഷോട്ട് എടുത്താൽ ആപ്പിന് അറിയിപ്പ് ലഭിക്കും."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM-ലേക്ക് കമാൻഡുകൾ അയയ്ക്കുക"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"സിമ്മിലേക്ക് കമാൻഡുകൾ അയയ്ക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് വളരെ അപകടകരമാണ്."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ശാരീരിക പ്രവർത്തനം തിരിച്ചറിയുക"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ഫോണിന്റെ ക്യാമറ ആക്സസ് ചെയ്യാനാകില്ല"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ടാബ്ലെറ്റിന്റെ ക്യാമറ ആക്സസ് ചെയ്യാനാകില്ല"</string> <string name="vdm_secure_window" msgid="161700398158812314">"സ്ട്രീം ചെയ്യുമ്പോൾ ഇത് ആക്സസ് ചെയ്യാനാകില്ല. പകരം നിങ്ങളുടെ ഫോണിൽ ശ്രമിച്ച് നോക്കൂ."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"സ്ട്രീമിംഗിനിടെ ചിത്രത്തിനുള്ളിൽ ചിത്രം കാണാനാകില്ല"</string> <string name="system_locale_title" msgid="711882686834677268">"സിസ്റ്റം ഡിഫോൾട്ട്"</string> <string name="default_card_name" msgid="9198284935962911468">"കാർഡ് <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 114d562821f0..0fd3c6f28534 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Апп нь өөрийн хэсгийг санах ойд байнга байлгах боломжтой. Энэ нь бусад апп-уудын ашиглах санах ойг хязгаарлан утсыг удаашруулах болно."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"интерактив (foreground) үйлчилгээг ажиллуулах"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Аппад интерактив (foreground) үйлчилгээг ашиглахыг зөвшөөрнө үү."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"Камер\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Аппад \"камер\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"ConnectedDevice\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Аппад \"connectedDevice\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"DataSync\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Аппад \"dataSync\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"Байршил\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Аппад \"байршил\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"MediaPlayback\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Аппад \"mediaPlayback\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"MediaProjection\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Аппад \"mediaProjection\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"Микрофон\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Аппад \"микрофон\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"PhoneCall\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Аппад \"phoneCall\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"Эрүүл мэнд\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Аппад \"эрүүл мэнд\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"RemoteMessaging\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Аппад \"remoteMessaging\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"SystemExempted\"-н төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Аппад \"systemExempted\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"SpecialUse\" төрөлтэй нүүрэн талын үйлчилгээг ажиллуулах"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Аппад \"specialUse\" төрөлтэй нүүрэн талын үйлчилгээнүүдийг ашиглахыг зөвшөөрнө"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"апп сангийн хэмжээг хэмжих"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Апп нь өөрийн код, дата болон кеш хэмжээг унших боломжтой"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"систем тохиргоог өөрчлөх"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с утасны камерт хандах боломжгүй"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с таблетын камерт хандах боломжгүй"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Стримингийн үед үүнд хандах боломжгүй. Оронд нь утас дээрээ туршиж үзнэ үү."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Дамжуулах явцад дэлгэц доторх дэлгэцийг үзэх боломжгүй"</string> <string name="system_locale_title" msgid="711882686834677268">"Системийн өгөгдмөл"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 216d960f75cb..a4121dea4ab6 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"अॅप ला मेमरीमध्ये कायम असलेले त्याचे स्वतःचे भाग बनविण्यास अनुमती देते. हे फोन धीमा करून अन्य अॅप्सवर उपलब्ध असलेल्या मेमरीवर मर्यादा घालू शकते."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"पृष्ठभाग सेवा रन करा"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"अॅपला पृष्ठभाग सेवा वापरण्याची अनुमती देते."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"कॅमेरा\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"\"कॅमेरा\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"\"connectedDevice\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"\"dataSync\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"स्थान\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"\"स्थान\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"\"mediaPlayback\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"\"mediaProjection\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"मायक्रोफोन\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"\"मायक्रोफोन\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"\"phoneCall\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"आरोग्य\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"\"आरोग्य\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"\"remoteMessaging\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"\"systemExempted\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" प्रकारासोबत फोरग्राउंड सेवा रन करा"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"\"specialUse\" प्रकारासोबत अॅपला फोरग्राउंड सेवांचा वापर करण्याची अनुमती देते"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"अॅप संचयन स्थान मोजा"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"अॅप ला त्याचा कोड, डेटा आणि कॅशे आकार पुनर्प्राप्त करण्यासाठी अनुमती देते"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टीम सेटिंग्ज सुधारित करा"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ॲप वापरात असताना, हे ॲप मायक्रोफोन वापरून ऑडिओ रेकॉर्ड करू शकते."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"बॅकग्राउंडमध्ये ऑडिओ रेकॉर्ड करा"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"हे ॲप मायक्रोफोन वापरून ऑडिओ कधीही रेकॉर्ड करू शकते."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"अॅप विंडोचे स्क्रीन कॅप्चर डिटेक्ट करा"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"ॲप वापरात असताना स्क्रीनशॉट घेतल्यावर या ॲपला सूचित केले जाईल."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"सिम वर कमांड पाठवा"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"अॅप ला सिम वर कमांड पाठविण्याची अनुमती देते. हे खूप धोकादायक असते."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"शारीरिक ॲक्टिव्हिटी ओळखा"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून फोनचा कॅमेरा अॅक्सेस करू शकत नाही"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून टॅबलेटचा कॅमेरा अॅक्सेस करू शकत नाही"</string> <string name="vdm_secure_window" msgid="161700398158812314">"स्ट्रीम करताना हे अॅक्सेस केले जाऊ शकत नाही. त्याऐवजी तुमच्या फोनवर अॅक्सेस करून पहा."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"स्ट्रीम होत असताना चित्रात-चित्र पाहू शकत नाही"</string> <string name="system_locale_title" msgid="711882686834677268">"सिस्टीम डीफॉल्ट"</string> <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 112190b8d0fa..5faec0a244f6 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Membenarkan apl untuk membuat sebahagian dari dirinya berterusan dalam memori. Ini boleh mengehadkan memori yang tersedia kepada apl lain dan menjadikan telefon perlahan."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"jalankan perkhidmatan latar depan"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Membenarkan apl menggunakan perkhidmatan latar depan."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"jalankan perkhidmatan latar depan dengan jenis \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"jalankan perkhidmatan latar depan dengan jenis \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"jalankan perkhidmatan latar depan dengan jenis \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"jalankan perkhidmatan latar depan dengan jenis \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"jalankan perkhidmatan latar depan dengan jenis \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"jalankan perkhidmatan latar depan dengan jenis \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"jalankan perkhidmatan latar depan dengan jenis \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"jalankan perkhidmatan latar depan dengan jenis \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"jalankan perkhidmatan latar depan dengan jenis \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"jalankan perkhidmatan latar depan dengan jenis \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"jalankan perkhidmatan latar depan dengan jenis \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"jalankan perkhidmatan latar depan dengan jenis \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Membenarkan apl menggunakan perkhidmatan latar depan dengan jenis \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ukur ruang storan apl"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Membenarkan apl mendapatkan semula kodnya, datanya dan saiz cachenya"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ubah suai tetapan sistem"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera telefon daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Kandungan ini tidak boleh diakses semasa penstriman. Cuba pada telefon anda."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Tidak dapat melihat gambar dalam gambar semasa penstriman"</string> <string name="system_locale_title" msgid="711882686834677268">"Lalai sistem"</string> <string name="default_card_name" msgid="9198284935962911468">"KAD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 8e9b9adb972f..6f45b9383905 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"အပလီကေးရှင်းအား မှတ်ဉာဏ်ထဲတွင် ရေရှည်သိမ်းဆည်ထားရန် ခွင့်ပြုပါ။ ဒီခွင့်ပြုချက်ကြောင့် တခြားအပလီကေးရှင်းအများအတွက် မှတ်ဉာဏ်ရရှိမှု နည်းသွားနိုင်ပြီး ဖုန်းလည်း နှေးသွားနိုင်ပါသည်။"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"မျက်နှာစာ ဝန်ဆောင်မှုကို ဖွင့်ခြင်း"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"မျက်နှာစာဝန်ဆောင်မှုများကို အက်ပ်အား အသုံးပြုခွင့်ပေးသည်။"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"\"camera\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"\"connectedDevice\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"\"dataSync\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"\"location\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"\"mediaPlayback\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"\"mediaProjection\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"\"microphone\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"\"phoneCall\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"\"health\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"\"remoteMessaging\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"\"systemExempted\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှု လုပ်ဆောင်ခြင်း"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"\"specialUse\" အမျိုးအစား မျက်နှာစာဝန်ဆောင်မှုများအား အကျိုးရှိရှိ အသုံးပြုနိုင်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"အက်ပ်သိုလှောင်မှု နေရာကို တိုင်းထွာခြင်း"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"အက်ပ်အား ၎င်း၏ ကုဒ်၊ ဒေတာ၊ နှင့် ကက်ရှ ဆိုက်များကို ရယူခွင့် ပြုသည်။"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"စနစ်အပြင်အဆင်အား မွမ်းမံခြင်း"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ဤအက်ပ်ကို အသုံးပြုနေစဉ် ၎င်းက မိုက်ခရိုဖုန်းကို အသုံးပြု၍ အသံဖမ်းနိုင်သည်။"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"နောက်ခံတွင် အသံဖမ်းပါ"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"ဤအက်ပ်သည် မိုက်ခရိုဖုန်းကို အသုံးပြု၍ အချိန်မရွေး အသံဖမ်းနိုင်သည်။"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"အက်ပ်ဝင်းဒိုး၏ ဖန်သားပြင်ပုံဖမ်းမှုကို သိရှိခြင်း"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"အက်ပ်သုံးနေစဉ် ဖန်သားပြင်ဓာတ်ပုံရိုက်သည့်အခါ ဤအက်ပ်က အကြောင်းကြားချက်ရရှိမည်။"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM ထံသို့ ညွှန်ကြားချက်များကို ပို့ပါ"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"အက်ပ်အား ဆင်းမ်ကဒ်ဆီသို့ အမိန့်များ ပေးပို့ခွင့် ပြုခြင်း။ ဤခွင့်ပြုမှုမှာ အန္တရာယ်အလွန် ရှိပါသည်။"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ကိုယ်ခန္ဓာလှုပ်ရှားမှုကို မှတ်သားပါ"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ ဖုန်းကင်မရာကို သုံး၍မရပါ"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ တက်ဘလက်ကင်မရာကို သုံး၍မရပါ"</string> <string name="vdm_secure_window" msgid="161700398158812314">"တိုက်ရိုက်လွှင့်နေစဉ် ၎င်းကို မသုံးနိုင်ပါ။ ၎င်းအစား ဖုန်းတွင် စမ်းကြည့်ပါ။"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"တိုက်ရိုက်လွှင့်စဉ် နှစ်ခုထပ်၍ မကြည့်နိုင်ပါ"</string> <string name="system_locale_title" msgid="711882686834677268">"စနစ်မူရင်း"</string> <string name="default_card_name" msgid="9198284935962911468">"ကတ် <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index dc8be27ff47d..0a940f1cf405 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Lar appen gjøre deler av seg selv vedvarende i minnet. Dette kan begrense minnet for andre apper og gjøre telefonen treg."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"kjøre tjenesten i forgrunnen"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Lar appen bruke tjenester i forgrunnen."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"kjøre forgrunnstjeneste med typen «camera»"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Lar appen bruke forgrunnstjenester med typen «camera»"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"kjøre forgrunnstjeneste med typen «connectedDevice»"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Lar appen bruke forgrunnstjenester med typen «connectedDevice»"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"kjøre forgrunnstjeneste med typen «dataSync»"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Lar appen bruke forgrunnstjenester med typen «dataSync»"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"kjøre forgrunnstjeneste med typen «location»"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Lar appen bruke forgrunnstjenester med typen «location»"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"kjøre forgrunnstjeneste med typen «mediaPlayback»"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Lar appen bruke forgrunnstjenester med typen «mediaPlayback»"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"kjøre forgrunnstjeneste med typen «mediaProjection»"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Lar appen bruke forgrunnstjenester med typen «mediaProjection»"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"kjøre forgrunnstjeneste med typen «microphone»"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Lar appen bruke forgrunnstjenester med typen «microphone»"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"kjøre forgrunnstjeneste med typen «phoneCall»"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Lar appen bruke forgrunnstjenester med typen «phoneCall»"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"kjøre forgrunnstjeneste med typen «health»"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Lar appen bruke forgrunnstjenester med typen «health»"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"kjøre forgrunnstjeneste med typen «remoteMessaging»"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Lar appen bruke forgrunnstjenester med typen «remoteMessaging»"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"kjøre forgrunnstjeneste med typen «systemExempted»"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Lar appen bruke forgrunnstjenester med typen «systemExempted»"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"kjøre forgrunnstjeneste med typen «specialUse»"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Lar appen bruke forgrunnstjenester med typen «specialUse»"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"måle lagringsplass for apper"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Lar appen hente ut koden, dataene og bufferstørrelsene til appen"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"endre systeminnstillingene"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Denne appen kan ta opp lyd med mikrofonen mens den er i bruk."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ta opp lyd i bakgrunnen"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Denne appen kan når som helst ta opp lyd med mikrofonen."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"registrere skjermdumper av appvinduer"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Denne appen varsles hvis det tas skjermdumper mens appen er i bruk."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"sende kommandoer til SIM-kortet"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Lar appen sende kommandoer til SIM-kortet. Dette er veldig farlig."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"gjenkjenn fysisk aktivitet"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Det er ikke mulig å få tilgang til telefonkameraet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Det er ikke mulig å få tilgang til kameraet på nettbrettet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Dette er ikke tilgjengelig under strømming. Prøv på telefonen i stedet."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Kan ikke se bilde-i-bilde under strømming"</string> <string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string> <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index b031aa8138db..9b25f8a4cf81 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"एपलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य एपहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"अग्रभूमिको सेवा सञ्चालन गर्नुहोस्"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"एपलाई अग्रभूमिका सेवाहरू प्रयोग गर्ने अनुमति दिन्छ।"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"यसले एपलाई \"camera\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"यसले एपलाई \"connectedDevice\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"यसले एपलाई \"dataSync\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"यसले एपलाई \"location\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"यसले एपलाई \"mediaPlayback\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"यसले एपलाई \"mediaProjection\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"यसले एपलाई \"microphone\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"यसले एपलाई \"phoneCall\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"यसले एपलाई \"health\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"यसले एपलाई \"remoteMessaging\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"यसले एपलाई \"systemExempted\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"यसले एपलाई \"specialUse\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"एप भण्डारण ठाउँको मापन गर्नुहोस्"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"एपलाई यसको कोड, डेटा, र क्यास आकारहरू पुनःप्राप्त गर्न अनुमति दिन्छ।"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"प्रणाली सेटिङहरू परिमार्जन गर्नुहोस्"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"यो एप प्रयोग भइरहेका बेला यसले माइक्रोफोन प्रयोग गरेर अडियो रेकर्ड गर्न सक्छ।"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ब्याकग्राउन्डमा अडियो रेकर्ड गर्नुहोस्"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"यो एपले जुनसुकै बेला माइक्रोफोन प्रयोग गरी अडियो रेकर्ड गर्न सक्छ।"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"एपको विन्डोको स्क्रिन क्याप्चर गरेको कुरा पत्ता लगाउनुहोस्"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"एप प्रयोग भइरहेको बेला स्क्रिनसट लिइयो भने यो एपलाई सूचना दिइने छ।"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM मा आदेशहरू पठाउन दिनुहोस्"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"SIM लाई आदेश पठाउन एपलाई अनुमति दिन्छ। यो निकै खतरनाक हुन्छ।"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"शारीरिक गतिविधि पहिचान गर्नुहोस्"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत फोनको क्यामेरा प्रयोग गर्न मिल्दैन"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत ट्याब्लेटको क्यामेरा प्रयोग गर्न मिल्दैन"</string> <string name="vdm_secure_window" msgid="161700398158812314">"स्ट्रिम गरिरहेका बेला यो सामग्री हेर्न तथा प्रयोग गर्न मिल्दैन। बरु आफ्नो फोनमार्फत सो सामग्री हेर्ने तथा प्रयोग गर्ने प्रयास गर्नुहोस्।"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"स्ट्रिम गरिरहेका बेला picture-in-picture मोड प्रयोग गर्न मिल्दैन"</string> <string name="system_locale_title" msgid="711882686834677268">"सिस्टम डिफल्ट"</string> <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 566bbb36212e..07413e6b4e30 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Hiermee kan de app gedeelten van zichzelf persistent maken in het geheugen. Dit kan de hoeveelheid geheugen beperken die beschikbaar is voor andere apps, waardoor de telefoon trager kan worden."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"service op de voorgrond uitvoeren"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Hiermee kan de app gebruikmaken van services op de voorgrond."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"service op de voorgrond van het type \'camera\' uitvoeren"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'camera\'"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"service op de voorgrond van het type \'connectedDevice\' uitvoeren"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'connectedDevice\'"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"service op de voorgrond van het type \'dataSync\' uitvoeren"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'dataSync\'"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"service op de voorgrond van het type \'location\' uitvoeren"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'location\'"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"service op de voorgrond van het type \'mediaPlayback\' uitvoeren"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'mediaPlayback\'"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"service op de voorgrond van het type \'mediaProjection\' uitvoeren"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'mediaProjection\'"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"service op de voorgrond van het type \'microphone\' uitvoeren"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'microphone\'"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"service op de voorgrond van het type \'phoneCall\' uitvoeren"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'phoneCall\'"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"service op de voorgrond van het type \'health\' uitvoeren"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'health\'"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"service op de voorgrond van het type \'remoteMessaging\' uitvoeren"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'remoteMessaging\'"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"service op de voorgrond van het type \'systemExempted\' uitvoeren"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'systemExempted\'"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"service op de voorgrond van het type \'specialUse\' uitvoeren"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Hiermee kan de app gebruikmaken van services op de voorgrond van het type \'specialUse\'"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"opslagruimte van app meten"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Hiermee kan de app de bijbehorende code, gegevens en cachegrootten ophalen."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"systeeminstellingen aanpassen"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Deze app kan audio opnemen met de microfoon als de app wordt gebruikt."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"audio opnemen op de achtergrond"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Deze app kan altijd audio opnemen met de microfoon."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"schermopnamen van de app vastleggen"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Deze app krijgt een melding als een screenshot wordt gemaakt terwijl de app in gebruik is."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"opdrachten verzenden naar de simkaart"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Hiermee kan de app opdrachten verzenden naar de simkaart. Dit is erg gevaarlijk."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"fysieke activiteit herkennen"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan geen toegang tot de camera van de telefoon krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan geen toegang tot de camera van de tablet krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Je hebt hier geen toegang toe tijdens streaming. Probeer het in plaats daarvan op je telefoon."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Kan scherm-in-scherm niet bekijken tijdens het streamen"</string> <string name="system_locale_title" msgid="711882686834677268">"Systeemstandaard"</string> <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 26880c547225..5206994026db 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"ଆପ୍ଟି ନିଜକୁ ମେମୋରୀରେ ଭାଗ କରିବାକୁ ଦେଇଥାଏ। ଏହାଦ୍ୱାରା ଅନ୍ୟ ଆପ୍ଗୁଡ଼ିକ ପାଇଁ ମେମୋରୀ ଉପଲବ୍ଧକୁ କମ୍ କରିବା ସହ ଫୋନ୍ଟିକୁ ମନ୍ଥର କରିବ।"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ଫୋର୍ଗ୍ରାଉଣ୍ଡ ସେବାକୁ ଚଲାନ୍ତୁ"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ଫୋର୍ଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦିଅନ୍ତୁ।"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"\"camera\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"\"connectedDevice\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"\"dataSync\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"\"location\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"\"mediaPlayback\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"\"mediaProjection\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"\"microphone\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"\"phoneCall\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"\"health\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"\"remoteMessaging\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"\"systemExempted\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ଚଲାଏ"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"\"specialUse\" ପ୍ରକାର ସହ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ଆପ୍ ଷ୍ଟୋରେଜ୍ ସ୍ଥାନର ମାପ କରନ୍ତୁ"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"ଆପ୍ର କୋଡ୍, ଡାଟା ଓ କ୍ୟାଶ୍ ଆକାର ହାସଲ କରିବା ପାଇଁ ଏହାକୁ ଅନୁମତି ଦେଇଥାଏ।"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ସିଷ୍ଟମ୍ ସେଟିଂସ ବଦଳାନ୍ତୁ"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଫୋନର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଟାବଲେଟର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ଷ୍ଟ୍ରିମ କରିବା ସମୟରେ ଏହାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଫୋନରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"ଷ୍ଟ୍ରିମ କରିବା ସମୟରେ ପିକଚର-ଇନ-ପିକଚର ଦେଖାଯାଇପାରିବ ନାହିଁ"</string> <string name="system_locale_title" msgid="711882686834677268">"ସିଷ୍ଟମ ଡିଫଲ୍ଟ"</string> <string name="default_card_name" msgid="9198284935962911468">"କାର୍ଡ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 6727f74c02d5..ace0d94a8b59 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਫ਼ੋਨ ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਾਂ ਤੇ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ਫੋਰਗ੍ਰਾਉਂਡ ਸੇਵਾਵਾਂ ਚਲਾਓ"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ਐਪ ਨੂੰ ਫੋਰਗ੍ਰਾਉਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦਿਓ।"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"ਐਪ ਨੂੰ \"camera\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"ਐਪ ਨੂੰ \"connectedDevice\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"ਐਪ ਨੂੰ \"dataSync\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"ਐਪ ਨੂੰ \"location\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"ਐਪ ਨੂੰ \"mediaPlayback\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"ਐਪ ਨੂੰ \"mediaProjection\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"ਐਪ ਨੂੰ \"microphone\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"ਐਪ ਨੂੰ \"phoneCall\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"ਐਪ ਨੂੰ \"health\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"ਐਪ ਨੂੰ \"remoteMessaging\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"ਐਪ ਨੂੰ \"systemExempted\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਨੂੰ ਚਲਾਉਂਦੀ ਹੈ"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"ਐਪ ਨੂੰ \"specialUse\" ਕਿਸਮ ਨਾਲ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ਐਪ ਸਟੋਰੇਜ ਜਗ੍ਹਾ ਮਾਪੋ"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"ਐਪ ਨੂੰ ਇਸਦਾ ਕੋਡ, ਡਾਟਾ ਅਤੇ ਕੈਸ਼ੇ ਆਕਾਰ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ਇਹ ਐਪ ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ ਵੇਲੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਵਰਤ ਕੇ ਆਡੀਓ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ।"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਆਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"ਇਹ ਐਪ ਕਿਸੇ ਵੇਲੇ ਵੀ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਵਰਤ ਕੇ ਆਡੀਓ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ।"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ਐਪ ਵਿੰਡੋਆਂ ਦੇ ਸਕ੍ਰੀਨ ਕੈਪਚਰਾਂ ਦਾ ਪਤਾ ਲਗਾਓ"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"ਐਪ ਦੇ ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ ਦੌਰਾਨ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ \'ਤੇ ਇਸ ਐਪ ਨੂੰ ਸੂਚਨਾ ਪ੍ਰਾਪਤ ਹੋਵੇਗੀ।"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM ਨੂੰ ਕਮਾਂਡਾਂ ਭੇਜੋ"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"ਐਪ ਨੂੰ SIM ਨੂੰ ਕਮਾਂਡਾਂ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਬਹੁਤ ਘਾਤਕ ਹੈ।"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ਸਰੀਰਕ ਸਰਗਰਮੀ ਨੂੰ ਪਛਾਣਨਾ"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਫ਼ੋਨ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਟੈਬਲੈੱਟ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ਸਟ੍ਰੀਮਿੰਗ ਦੌਰਾਨ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"ਸਟ੍ਰੀਮਿੰਗ ਦੌਰਾਨ ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ ਨਹੀਂ ਦੇਖੀ ਜਾ ਸਕਦੀ"</string> <string name="system_locale_title" msgid="711882686834677268">"ਸਿਸਟਮ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string> <string name="default_card_name" msgid="9198284935962911468">"ਕਾਰਡ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 0441a5ffaccb..a62873ee494a 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -497,10 +497,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ta aplikacja może nagrywać dźwięk przy użyciu mikrofonu, gdy jest używana."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"nagrywanie dźwięku w tle"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ta aplikacja może w dowolnym momencie nagrywać dźwięk przy użyciu mikrofonu."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"wykrywanie zrzutów ekranu z oknami aplikacji"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ta aplikacja będzie powiadamiana o zrzutach ekranu robionych po jej uruchomieniu."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"wysyłanie poleceń do karty SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Pozwala aplikacji na wysyłanie poleceń do karty SIM. To bardzo niebezpieczne."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"rozpoznawanie aktywności fizycznej"</string> @@ -2344,8 +2342,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nie można korzystać z aparatu telefonu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nie można korzystać z aparatu tabletu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Nie można z tego skorzystać podczas strumieniowania. Użyj telefonu."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Podczas strumieniowania nie można wyświetlać obrazu w obrazie"</string> <string name="system_locale_title" msgid="711882686834677268">"Ustawienie domyślne systemu"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index f4a654b8b1a7..a9830e71623c 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permite que o app torne partes de si mesmo persistentes na memória. Pode limitar a memória disponível para outros apps, deixando o telefone mais lento."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"executar serviço em primeiro plano"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permite que o app use serviços em primeiro plano."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"executar serviços em primeiro plano com o tipo \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Permite que o app use serviços em primeiro plano com o tipo \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"executar serviços em primeiro plano com o tipo \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Permite que o app use serviços em primeiro plano com o tipo \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"executar serviços em primeiro plano com o tipo \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Permite que o app use serviços em primeiro plano com o tipo \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"executar serviços em primeiro plano com o tipo \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Permite que o app use serviços em primeiro plano com o tipo \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"executar serviços em primeiro plano com o tipo \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Permite que o app use serviços em primeiro plano com o tipo \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"executar serviços em primeiro plano com o tipo \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Permite que o app use serviços em primeiro plano com o tipo \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"executar serviços em primeiro plano com o tipo \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Permite que o app use serviços em primeiro plano com o tipo \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"executar serviços em primeiro plano com o tipo \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Permite que o app use serviços em primeiro plano com o tipo \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"executar serviços em primeiro plano com o tipo \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Permite que o app use serviços em primeiro plano com o tipo \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"executar serviços em primeiro plano com o tipo \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Permite que o app use serviços em primeiro plano com o tipo \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"executar serviços em primeiro plano com o tipo \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Permite que o app use serviços em primeiro plano com o tipo \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"executar serviços em primeiro plano com o tipo \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Permite que o app use serviços em primeiro plano com o tipo \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"medir o espaço de armazenamento do app"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permite que o app recupere o código, os dados e os tamanhos de cache"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modificar configurações do sistema"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Enquanto está sendo usado, este app pode gravar áudio usando o microfone."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar áudio em segundo plano"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Este app pode gravar áudio usando o microfone a qualquer momento."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"detectar capturas de tela de janelas do app"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"O app vai ser notificado quando uma captura de tela for tirada enquanto ele estiver em uso."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos para o chip"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que o app envie comandos ao chip. Muito perigoso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconhecer atividade física"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Não é possível acessar esse conteúdo durante o streaming. Tente pelo smartphone."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Não é possível usar o modo picture-in-picture durante o streaming"</string> <string name="system_locale_title" msgid="711882686834677268">"Padrão do sistema"</string> <string name="default_card_name" msgid="9198284935962911468">"CHIP <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index a72cf674b8e7..e2966a2bebc2 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permite que a app torne partes de si mesma persistentes na memória. Isto pode limitar a disponibilidade da memória para outras aplicações, tornando o telemóvel mais lento."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"executar serviço em primeiro plano"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permite que a app utilize serviços em primeiro plano."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"executar o serviço em primeiro plano com o tipo \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Permite que a app use serviços em primeiro plano com o tipo \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"executar o serviço em primeiro plano com o tipo \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Permite que a app use serviços em primeiro plano com o tipo \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"executar o serviço em primeiro plano com o tipo \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Permite que a app use serviços em primeiro plano com o tipo \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"executar o serviço em primeiro plano com o tipo \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Permite que a app use serviços em primeiro plano com o tipo \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"executar o serviço em primeiro plano com o tipo \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Permite que a app use serviços em primeiro plano com o tipo \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"executar o serviço em primeiro plano com o tipo \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Permite que a app use serviços em primeiro plano com o tipo \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"executar o serviço em primeiro plano com o tipo \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Permite que a app use serviços em primeiro plano com o tipo \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"executar o serviço em primeiro plano com o tipo \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Permite que a app use serviços em primeiro plano com o tipo \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"executar o serviço em primeiro plano com o tipo \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Permite que a app use serviços em primeiro plano com o tipo \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"executar o serviço em primeiro plano com o tipo \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Permite que a app use serviços em primeiro plano com o tipo \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"executar o serviço em primeiro plano com o tipo \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Permite que a app use serviços em primeiro plano com o tipo \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"executar o serviço em primeiro plano com o tipo \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Permite que a app use serviços em primeiro plano com o tipo \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"medir espaço de armazenamento da app"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permite à app obter o código, os dados e o tamanhos de cache da mesma"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modificar as definições do sistema"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index f4a654b8b1a7..a9830e71623c 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permite que o app torne partes de si mesmo persistentes na memória. Pode limitar a memória disponível para outros apps, deixando o telefone mais lento."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"executar serviço em primeiro plano"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permite que o app use serviços em primeiro plano."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"executar serviços em primeiro plano com o tipo \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Permite que o app use serviços em primeiro plano com o tipo \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"executar serviços em primeiro plano com o tipo \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Permite que o app use serviços em primeiro plano com o tipo \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"executar serviços em primeiro plano com o tipo \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Permite que o app use serviços em primeiro plano com o tipo \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"executar serviços em primeiro plano com o tipo \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Permite que o app use serviços em primeiro plano com o tipo \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"executar serviços em primeiro plano com o tipo \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Permite que o app use serviços em primeiro plano com o tipo \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"executar serviços em primeiro plano com o tipo \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Permite que o app use serviços em primeiro plano com o tipo \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"executar serviços em primeiro plano com o tipo \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Permite que o app use serviços em primeiro plano com o tipo \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"executar serviços em primeiro plano com o tipo \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Permite que o app use serviços em primeiro plano com o tipo \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"executar serviços em primeiro plano com o tipo \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Permite que o app use serviços em primeiro plano com o tipo \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"executar serviços em primeiro plano com o tipo \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Permite que o app use serviços em primeiro plano com o tipo \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"executar serviços em primeiro plano com o tipo \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Permite que o app use serviços em primeiro plano com o tipo \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"executar serviços em primeiro plano com o tipo \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Permite que o app use serviços em primeiro plano com o tipo \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"medir o espaço de armazenamento do app"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permite que o app recupere o código, os dados e os tamanhos de cache"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modificar configurações do sistema"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Enquanto está sendo usado, este app pode gravar áudio usando o microfone."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar áudio em segundo plano"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Este app pode gravar áudio usando o microfone a qualquer momento."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"detectar capturas de tela de janelas do app"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"O app vai ser notificado quando uma captura de tela for tirada enquanto ele estiver em uso."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos para o chip"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que o app envie comandos ao chip. Muito perigoso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconhecer atividade física"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Não é possível acessar esse conteúdo durante o streaming. Tente pelo smartphone."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Não é possível usar o modo picture-in-picture durante o streaming"</string> <string name="system_locale_title" msgid="711882686834677268">"Padrão do sistema"</string> <string name="default_card_name" msgid="9198284935962911468">"CHIP <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 3f9c0b5a8efe..d300dfa612bf 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permite aplicației să declare persistente în memorie anumite părți ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcționarea telefonului."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"să ruleze serviciul în prim plan"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permite aplicației să utilizeze serviciile din prim-plan."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"să folosească serviciile în prim-plan cu tipul „camera”"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Permite aplicației să folosească serviciile în prim-plan cu tipul „camera”"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"să folosească serviciile în prim-plan cu tipul „connectedDevice”"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Permite aplicației să folosească serviciile în prim-plan cu tipul „connectedDevice”"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"să folosească serviciile în prim-plan cu tipul „dataSync”"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Permite aplicației să folosească serviciile în prim-plan cu tipul „dataSync”"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"să folosească serviciile în prim-plan cu tipul „location”"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Permite aplicației să folosească serviciile în prim-plan cu tipul „location”"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"să folosească serviciile în prim-plan cu tipul „mediaPlayback”"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Permite aplicației să folosească serviciile în prim-plan cu tipul „mediaPlayback”"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"să folosească serviciile în prim-plan cu tipul „mediaProjection”"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Permite aplicației să folosească serviciile în prim-plan cu tipul „mediaProjection”"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"să folosească serviciile în prim-plan cu tipul „microphone”"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Permite aplicației să folosească serviciile în prim-plan cu tipul „microphone”"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"să folosească serviciile în prim-plan cu tipul „phoneCall”"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Permite aplicației să folosească serviciile în prim-plan cu tipul „phoneCall”"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"să folosească serviciile în prim-plan cu tipul „health”"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Permite aplicației să folosească serviciile în prim-plan cu tipul „health”"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"să folosească serviciile în prim-plan cu tipul „remoteMessaging”"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Permite aplicației să folosească serviciile în prim-plan cu tipul „remoteMessaging”"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"să folosească serviciile în prim-plan cu tipul „systemExempted”"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Permite aplicației să folosească serviciile în prim-plan cu tipul „systemExempted”"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"să folosească serviciile în prim-plan cu tipul „specialUse”"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Permite aplicației să folosească serviciile în prim-plan cu tipul „specialUse”"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"măsurare spațiu de stocare al aplicației"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permite aplicației să preia dimensiunile codului, ale datelor și ale memoriei cache"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modifică setări de sistem"</string> @@ -2341,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nu se poate accesa camera foto a telefonului de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nu se poate accesa camera foto a tabletei de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Nu se poate accesa în timpul streamingului. Încearcă pe telefon."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Nu se poate viziona picture-in-picture în timpul streamingului"</string> <string name="system_locale_title" msgid="711882686834677268">"Prestabilit de sistem"</string> <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 33612de81197..36fa51bc67d7 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Приложение сможет постоянно хранить свои компоненты в памяти. Это может уменьшить объем памяти, доступный другим приложениям, и замедлить работу устройства."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"Запуск активных сервисов"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Разрешить приложению использовать активные сервисы."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"запускать активные службы с типом camera"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Разрешить приложению использовать активные службы с типом camera"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"запускать активные службы с типом connectedDevice"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Разрешить приложению использовать активные службы с типом connectedDevice"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"запускать активные службы с типом dataSync"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Разрешить приложению использовать активные службы с типом dataSync"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"запускать активные службы с типом location"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Разрешить приложению использовать активные службы с типом location"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"запускать активные службы с типом mediaPlayback"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Разрешить приложению использовать активные службы с типом mediaPlayback"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"запускать активные службы с типом mediaProjection"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Разрешить приложению использовать активные службы с типом mediaProjection"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"запускать активные службы с типом microphone"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Разрешить приложению использовать активные службы с типом microphone"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"запускать активные службы с типом phoneCall"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Разрешить приложению использовать активные службы с типом phoneCall"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"запускать активные службы с типом health"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Разрешить приложению использовать активные службы с типом health"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"запускать активные службы с типом remoteMessaging"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Разрешить приложению использовать активные службы с типом remoteMessaging"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"запускать активные службы с типом systemExempted"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Разрешить приложению использовать активные службы с типом systemExempted"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"запускать активные службы с типом specialUse"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Разрешить приложению использовать активные службы с типом specialUse"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"Вычисление объема памяти приложений"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Приложение сможет получать сведения о размере кода, данных и кеша."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"Изменение настроек системы"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Когда приложение используется, оно может записывать аудио с помощью микрофона."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"Записывать аудио в фоновом режиме"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Приложение может в любое время записывать аудио с помощью микрофона."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"Обнаруживать запись экрана, когда открыто окно приложения"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Если во время использования приложения будет сделан скриншот, оно получит уведомление."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"Отправка команд SIM-карте"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Приложение сможет отправлять команды SIM-карте (данное разрешение представляет большую угрозу)."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"Распознавать физическую активность"</string> @@ -2344,8 +2318,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"У устройства <xliff:g id="DEVICE">%1$s</xliff:g> нет доступа к камере телефона."</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"У устройства \"<xliff:g id="DEVICE">%1$s</xliff:g>\" нет доступа к камере планшета."</string> <string name="vdm_secure_window" msgid="161700398158812314">"Этот контент недоступен во время трансляции. Используйте телефон."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Нельзя запустить режим \"Картинка в картинке\" во время потоковой передачи"</string> <string name="system_locale_title" msgid="711882686834677268">"Системные настройки по умолчанию"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 3eab51b49563..4f9fb412f33d 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"යෙදුමට තම කොටස් මතකය තුල නොබිඳීව රඳා පවත්වාගෙන යාමට අවසර දෙන්න. මෙය දුරකථනය මන්දගාමී කරමින් අනෙකුත් උපාංගයන් සඳහා ඉතිරි මතකය සීමා කිරීමට හැක."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"පෙරබිම් සේවාව ධාවනය කරන්න"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"පෙරබිම් සේවා භාවිත කිරීමට යෙදුමට ඉඩ දෙයි."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"කැමරාව\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"\"කැමරාව\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"\"connectedDevice\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"\"dataSync\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"ස්ථානය\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"\"ස්ථානය\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"\"mediaPlayback\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"\"mediaProjection\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"මයික්රොෆෝනය\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"\"මයික්රොෆෝනය\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"\"phoneCall\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"සෞඛ්යය\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"\"සෞඛ්යය\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"\"remoteMessaging\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"\"systemExempted\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" වර්ගය සමග පෙරබිම් සේවාව ධාවනය කරන්න"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"\"specialUse\" වර්ගය සමග පෙරබිම් සේවා භාවිතා කිරීමට යෙදුමට ඉඩ දෙයි"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"යෙදුම් ආචයනයේ ඉඩ ප්රමාණය මැනීම"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"යෙදුමකට එහි කේතය, දත්ත සහ හැඹිලි ප්රමාණ ලබාගැනීමට අවසර දෙන්න."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"පද්ධති සැකසීම් වෙනස් කිරීම"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"මෙම යෙදුමට එය භාවිතයෙහි ඇති අතරතුර මයික්රෆෝනය භාවිත කර ඕඩියෝ පටිගත කිරීමට හැකිය."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"පසුබිමෙහි ඕඩියෝ පටිගත කරන්න"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"මෙම යෙදුමට ඕනෑම වේලාවක මයික්රෆෝනය භාවිත කර ඕඩියෝ පටිගත කිරීමට හැකිය."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"යෙදුම් කවුළුවල තිර ග්රහණ අනාවරණය කර ගන්න"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"යෙදුම භාවිතා කරන අතරේ තිර රුවක් ගත් විට මෙම යෙදුමට දැනුම් දෙනු ලැබේ."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM වෙත විධාන යැවීම"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"SIM වෙත විධාන ගෙන යාමට යෙදුමට අවසර දෙයි. මෙය ඉතා භයානක වේ."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"ශාරීරික ක්රියාකාරකම හඳුනා ගන්න"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් දුරකථනයේ කැමරාවට ප්රවේශ විය නොහැකිය"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් ටැබ්ලටයේ කැමරාවට ප්රවේශ විය නොහැකිය"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ප්රවාහය කරන අතරේ මෙයට ප්රවේශ විය නොහැක. ඒ වෙනුවට ඔබේ දුරකථනයෙහි උත්සාහ කරන්න."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"ප්රවාහය අතරේ පින්තූරයේ-පින්තූරය බැලිය නොහැක"</string> <string name="system_locale_title" msgid="711882686834677268">"පද්ධති පෙරනිමිය"</string> <string name="default_card_name" msgid="9198284935962911468">"කාඩ්පත <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index de86dfea8b2c..74d11ff385c4 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Umožňuje aplikácii uložiť niektoré svoje časti natrvalo do pamäte. Môže to obmedziť pamäť dostupnú pre ostatné aplikácie a spomaliť tak telefón."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"spustiť službu v popredí"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Umožňuje aplikácii používať služby v popredí"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"spustiť službu na popredí s typom camera"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Umožňuje aplikácii využívať služby na popredí s typom camera"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"spustiť službu na popredí s typom connectedDevice"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Umožňuje aplikácii využívať služby na popredí s typom connectedDevice"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"spustiť službu na popredí s typom dataSync"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Umožňuje aplikácii využívať služby na popredí s typom dataSync"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"spustiť službu na popredí s typom location"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Umožňuje aplikácii využívať služby na popredí s typom location"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"spustiť službu na popredí s typom mediaPlayback"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Umožňuje aplikácii využívať služby na popredí s typom mediaPlayback"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"spustiť službu na popredí s typom mediaProjection"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Umožňuje aplikácii využívať služby na popredí s typom mediaProjection"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"spustiť službu na popredí s typom microphone"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Umožňuje aplikácii využívať služby na popredí s typom microphone"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"spustiť službu na popredí s typom phoneCall"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Umožňuje aplikácii využívať služby na popredí s typom phoneCall"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"spustiť službu na popredí s typom health"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Umožňuje aplikácii využívať služby na popredí s typom health"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"spustiť službu na popredí s typom remoteMessaging"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Umožňuje aplikácii využívať služby na popredí s typom remoteMessaging"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"spustiť službu na popredí s typom systemExempted"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Umožňuje aplikácii využívať služby na popredí s typom dataSync systemExempted"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"spustiť službu na popredí s typom specialUse"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Umožňuje aplikácii využívať služby na popredí s typom specialUse"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"zistiť veľkosť ukladacieho priestoru aplikácie"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Umožňuje aplikácii načítať svoj kód, údaje a veľkosti vyrovnávacej pamäte"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"upraviť nastavenia systému"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Táto aplikácia môže nahrávať zvuk pomocou mikrofónu, keď ju používate."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"nahrávanie zvuku na pozadí"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Táto aplikácia môže kedykoľvek nahrávať zvuk pomocou mikrofónu."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"rozpoznávanie snímaní obrazovky zahŕňajúcich okná aplikácie"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Táto aplikácia dostane upozornenie, keď bude počas jej používania vytvorená snímka obrazovky."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"posielanie príkazov do SIM karty"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Umožňuje aplikácii odosielať príkazy na SIM kartu. Toto je veľmi nebezpečné povolenie."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"rozpoznávanie fyzickej aktivity"</string> @@ -2344,8 +2318,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere telefónu"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere tabletu"</string> <string name="vdm_secure_window" msgid="161700398158812314">"K tomuto obsahu nie je počas streamovania prístup. Skúste použiť telefón."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Počas streamingu sa obraz v obraze nedá zobraziť"</string> <string name="system_locale_title" msgid="711882686834677268">"Predvolené systémom"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 52c544100e71..0111719e1cff 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Aplikaciji omogoča, da nekatere svoje dele naredi trajne v pomnilniku. S tem je lahko pomnilnik omejen za druge aplikacije, zaradi česar je delovanje telefona upočasnjeno."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"Izvajanje storitve v ospredju"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Aplikaciji dovoljuje uporabo storitev v ospredju."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"izvajanje storitve v ospredju vrste »camera«"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »camera«."</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"izvajanje storitve v ospredju vrste »connectedDevice«"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »connectedDevice«."</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"izvajanje storitve v ospredju vrste »dataSync«"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »dataSync«."</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"izvajanje storitve v ospredju vrste »location«"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »location«."</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"izvajanje storitve v ospredju vrste »mediaPlayback«"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »mediaPlayback«."</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"izvajanje storitve v ospredju vrste »mediaProjection«"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »mediaProjection«."</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"izvajanje storitve v ospredju vrste »microphone«"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »microphone«."</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"izvajanje storitve v ospredju vrste »phoneCall«"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »phoneCall«."</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"izvajanje storitve v ospredju vrste »health«"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »health«."</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"izvajanje storitve v ospredju vrste »remoteMessaging«"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »remoteMessaging«."</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"izvajanje storitve v ospredju vrste »systemExempted«"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »systemExempted«."</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"izvajanje storitve v ospredju vrste »specialUse«"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Aplikaciji dovoljuje, da uporablja storitve v ospredju vrste »specialUse«."</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"izračunavanje prostora za shranjevanje aplikacije"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Aplikaciji omogoča, da pridobi njeno kodo, podatke in velikosti predpomnilnika."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"spreminjanje sistemskih nastavitev"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ta aplikacija lahko uporablja mikrofon za snemanje zvoka med uporabo aplikacije."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"snemanje zvoka v ozadju"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ta aplikacija lahko poljubno uporablja mikrofon za snemanje zvoka."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"zaznavanje zajemov zaslonskih slik v oknih aplikacij"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ta aplikacija bo obveščena o vsakem posnetku zaslona, ustvarjenem med njeno uporabo."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"pošiljanje ukazov na kartico SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Aplikaciji dovoli pošiljanje ukazov kartici SIM. To je lahko zelo nevarno."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje telesne dejavnosti"</string> @@ -2344,8 +2318,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ni mogoče dostopati do fotoaparata telefona prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ni mogoče dostopati do fotoaparata tabličnega računalnika prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string> <string name="vdm_secure_window" msgid="161700398158812314">"Do te vsebine ni mogoče dostopati med pretočnim predvajanjem. Poskusite s telefonom."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Slike v sliki ni mogoče prikazati med pretočnim predvajanjem."</string> <string name="system_locale_title" msgid="711882686834677268">"Sistemsko privzeto"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index d5c8c87c5e7a..799f483d66ed 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Lejon aplikacionin të zaptojë një pjesë të qëndrueshme në kujtesë. Kjo mund të kufizojë kujtesën e disponueshme për aplikacionet e tjera duke e ngadalësuar telefonin."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ekzekuto shërbimin në plan të parë"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Lejon aplikacionin të përdorë shërbimet në plan të parë."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"të ekzekutojë shërbimin në plan të parë me llojin \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"të ekzekutojë shërbimin në plan të parë me llojin \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"të ekzekutojë shërbimin në plan të parë me llojin \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"të ekzekutojë shërbimin në plan të parë me llojin \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"të ekzekutojë shërbimin në plan të parë me llojin \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"të ekzekutojë shërbimin në plan të parë me llojin \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"të ekzekutojë shërbimin në plan të parë me llojin \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"të ekzekutojë shërbimin në plan të parë me llojin \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"të ekzekutojë shërbimin në plan të parë me llojin \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"të ekzekutojë shërbimin në plan të parë me llojin \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"të ekzekutojë shërbimin në plan të parë me llojin \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"të ekzekutojë shërbimin në plan të parë me llojin \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Lejon që aplikacioni të përdorë shërbimet në plan të parë me llojin \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"mat hapësirën ruajtëse të aplikacionit"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Lejon aplikacionin të gjejë kodin e tij, të dhënat dhe madhësitë e memorieve të përkohshme."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"modifiko cilësimet e sistemit"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ky aplikacion mund të regjistrojë audion duke përdorur mikrofonin kur aplikacioni është në përdorim."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"të regjistrojë audion në sfond"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ky aplikacion mund të regjistrojë audion me mikrofonin në çdo kohë."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"të zbulojë regjistrimet e ekranit të dritareve të aplikacionit"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ky aplikacion do të njoftohet kur nxirret një pamje ekrani ndërkohë që aplikacioni është në përdorim."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"dërgo komanda te karta SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Lejon aplikacionin t\'i dërgojë komanda kartës SIM. Kjo është shumë e rrezikshme."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"njih aktivitetin fizik"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nuk mund të qasesh në kamerën e telefonit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nuk mund të qasesh në kamerën e tabletit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Nuk mund të kesh qasje në të gjatë transmetimit. Provoje në telefon më mirë."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Figura brenda figurës nuk mund të shikohet gjatë transmetimit"</string> <string name="system_locale_title" msgid="711882686834677268">"Parazgjedhja e sistemit"</string> <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 142d2dd902ca..f5de28489e1f 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -396,54 +396,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Дозвољава апликацији да учини сопствене компоненте трајним у меморији. Ово може да ограничи меморију доступну другим апликацијама и успори телефон."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"покрени услугу у првом плану"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Дозвољава апликацији да користи услуге у првом плану."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"покретање услуге у првом плану која припада типу „camera“"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „camera“"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"покретање услуге у првом плану која припада типу „connectedDevice“"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „connectedDevice“"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"покретање услуге у првом плану која припада типу „dataSync“"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „dataSync“"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"покретање услуге у првом плану која припада типу „location“"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „location“"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"покретање услуге у првом плану која припада типу „mediaPlayback“"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „mediaPlayback“"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"покретање услуге у првом плану која припада типу „mediaProjection“"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „mediaProjection“"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"покретање услуге у првом плану која припада типу „microphone“"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „microphone“"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"покретање услуге у првом плану која припада типу „phoneCall“"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „phoneCall“"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"покретање услуге у првом плану која припада типу „health“"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „health“"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"покретање услуге у првом плану која припада типу „remoteMessaging“"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „remoteMessaging“"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"покретање услуге у првом плану која припада типу „systemExempted“"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „systemExempted“"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"покретање услуге у првом плану која припада типу „specialUse“"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Дозвољава апликацији да користи услуге у првом плану које припадају типу „specialUse“"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"мерење меморијског простора у апликацији"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Дозвољава апликацији да преузме величине кôда, података и кеша."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"измена подешавања система"</string> @@ -496,10 +472,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ова апликација може да снима звук помоћу микрофона док се апликација користи."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"да снима звук у позадини"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ова апликација може да снима звук помоћу микрофона у било ком тренутку."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"откривање снимања екрана у прозорима апликација"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ако се током коришћења ове апликације направи снимак екрана, апликација ће добити обавештење."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"слање команди на SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Омогућава апликацији да шаље команде SIM картици. То је веома опасно."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"препознавање физичких активности"</string> @@ -2343,8 +2317,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се приступи камери телефона са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се приступи камери таблета са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Овом не можете да приступате током стримовања. Пробајте на телефону."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Не можете да гледате слику у слици при стримовању"</string> <string name="system_locale_title" msgid="711882686834677268">"Подразумевани системски"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТИЦА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index baeffd2f5e05..dec226a5effe 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Tillåter att delar av appen läggs beständigt i minnet. Detta kan innebära att det tillgängliga minnet för andra appar begränsas, vilket gör mobilen långsam."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"kör tjänst i förgrunden"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Tillåter att appen använder tjänster i förgrunden."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"kör förgrundstjänst av typen camera"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Tillåter att appen använder förgrundstjänster av typen camera"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"kör förgrundstjänst av typen connectedDevice"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Tillåter att appen använder förgrundstjänster av typen connectedDevice"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"kör förgrundstjänst av typen dataSync"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Tillåter att appen använder förgrundstjänster av typen dataSync"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"kör förgrundstjänst av typen location"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Tillåter att appen använder förgrundstjänster av typen location"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"kör förgrundstjänst av typen mediaPlayback"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Tillåter att appen använder förgrundstjänster av typen mediaPlayback"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"kör förgrundstjänst av typen mediaProjection"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Tillåter att appen använder förgrundstjänster av typen mediaProjection"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"kör förgrundstjänst av typen microphone"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Tillåter att appen använder förgrundstjänster av typen microphone"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"kör förgrundstjänst av typen phoneCall"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Tillåter att appen använder förgrundstjänster av typen phoneCall"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"kör förgrundstjänst av typen health"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Tillåter att appen använder förgrundstjänster av typen health"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"kör förgrundstjänst av typen remoteMessaging"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Tillåter att appen använder förgrundstjänster av typen remoteMessaging"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"kör förgrundstjänst av typen systemExempted"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Tillåter att appen använder förgrundstjänster av typen systemExempted"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"kör förgrundstjänst av typen specialUse"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Tillåter att appen använder förgrundstjänster av typen specialUse"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"mäta appens lagringsplats"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Tillåter att appen hämtar kod, data och cachestorlekar"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"ändra systeminställningar"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Appen kan ta spela in ljud med mikrofonen när appen används."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"spela in ljud i bakgrunden"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Appen kan spela in ljud med mikrofonen när som helst."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"upptäck skärmbilder/skärminspelningar av appfönster"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Den här appen informeras om en skärmbild tas när appen används."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"skicka kommandon till SIM-kortet"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Tillåter att appen skickar kommandon till SIM-kortet. Detta är mycket farligt."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"känn igen fysisk aktivitet"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Telefonens kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Surfplattans kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Det går inte att komma åt innehållet när du streamar. Testa med telefonen i stället."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Det går inte att visa bild-i-bild när du streamar"</string> <string name="system_locale_title" msgid="711882686834677268">"Systemets standardinställning"</string> <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index ea638852d79f..a68fcc8cf807 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -495,10 +495,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Programu hii inaweza kurekodi sauti kwa kutumia maikrofoni wakati programu inatumika."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"rekodi sauti chinichini"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Programu hii inaweza kurekodi sauti kwa kutumia maikrofoni wakati wowote."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"tambua picha za skrini za madirisha ya programu"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Programu hii itaarifiwa picha ya skrini itakapopigwa wakati programu inatumika."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"tuma amri kwenye SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Huruhusu programu kutuma amri kwa SIM. Hii ni hatari sana."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"itambue shughuli unazofanya"</string> @@ -2342,8 +2340,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Huwezi kufikia kamera ya simu kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Haiwezi kufikia kamera ya kompyuta kibao kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Huwezi kufikia maudhui haya unapotiririsha. Badala yake jaribu kwenye simu yako."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Huwezi kuona picha iliyopachikwa ndani ya picha nyingine unapotiririsha"</string> <string name="system_locale_title" msgid="711882686834677268">"Chaguomsingi la mfumo"</string> <string name="default_card_name" msgid="9198284935962911468">"SIM KADI <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 461ddbda72ef..20875bb85753 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -495,10 +495,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"இந்த ஆப்ஸ் உபயோகத்தில் இருக்கும்போதே இதனால் மைக்ரோஃபோனைப் பயன்படுத்தி ஆடியோவை ரெக்கார்டு செய்ய முடியும்."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"பின்புலத்தில் ஆடியோ ரெக்கார்டு செய்தல்"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"இந்த ஆப்ஸால் எப்போது வேண்டுமானாலும் மைக்ரோஃபோனைப் பயன்படுத்தி ஆடியோவை ரெக்கார்டு செய்ய முடியும்."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ஆப்ஸ் சாளரங்களில் திரையைப் படமெடுத்தலைக் கண்டறிதல்"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"இந்த ஆப்ஸ் பயன்பாட்டில் இருக்கும்போது ஸ்கிரீன்ஷாட் எடுக்கப்பட்டால் ஆப்ஸுக்கு அறிவிக்கப்படும்."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"கட்டளைகளை சிம்மிற்கு அனுப்புதல்"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"சிம் க்குக் கட்டளைகளை அனுப்ப ஆப்ஸை அனுமதிக்கிறது. இது மிகவும் ஆபத்தானதாகும்."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"உடல் செயல்பாட்டைக் கண்டறிதல்"</string> @@ -2342,8 +2340,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து மொபைலின் கேமராவை அணுக முடியாது"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து டேப்லெட்டின் கேமராவை அணுக முடியாது"</string> <string name="vdm_secure_window" msgid="161700398158812314">"ஸ்ட்ரீமின்போது இதை அணுக முடியாது. அதற்குப் பதிலாக உங்கள் மொபைலில் பயன்படுத்திப் பார்க்கவும்."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"ஸ்ட்ரீம் செய்யும்போது பிக்ச்சர்-இன்-பிக்ச்சர் அம்சத்தைப் பயன்படுத்த முடியாது"</string> <string name="system_locale_title" msgid="711882686834677268">"சிஸ்டத்தின் இயல்பு"</string> <string name="default_card_name" msgid="9198284935962911468">"கார்டு <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 37d43285a9ee..df8d773e02da 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"యాప్, దాని భాగాలు మెమరీలో ఉండేలా చేయడానికి దానిని అనుమతిస్తుంది. ఇది ఇతర యాప్లకు అందుబాటులో ఉన్న మెమరీని ఆక్రమిస్తుంది, ఫోన్ నెమ్మదిగా పని చేస్తుంది."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"సేవని ముందు భాగంలో అమలు చేయడం"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ముందు భాగంలో సేవలను ఉపయోగించడానికి యాప్ని అనుమతిస్తుంది."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"\"camera\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"\"connectedDevice\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"\"dataSync\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"\"location\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"\"mediaPlayback\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"\"mediaProjection\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"\"microphone\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"\"phoneCall\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"\"health\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించుకోవడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"\"remoteMessaging\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"\"systemExempted\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించడానికి యాప్ను అనుమతిస్తుంది"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" రకంతో ఫోర్గ్రౌండ్ సర్వీస్ను రన్ చేయండి"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"\"specialUse\" అనే రకంతో ఫోర్గ్రౌండ్ సర్వీస్లను ఉపయోగించడానికి యాప్ను అనుమతిస్తుంది"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"యాప్ నిల్వ స్థలాన్ని అంచనా వేయడం"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"యాప్ కోడ్, డేటా మరియు కాష్ పరిమాణాలను తిరిగి పొందడానికి దాన్ని అనుమతిస్తుంది"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"సిస్టమ్ సెట్టింగ్లను మార్చడం"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"యాప్ ఉపయోగంలో ఉన్నపుడు మైక్రోఫోన్ను ఉపయోగించి ఈ యాప్, ఆడియోను రికార్డ్ చేయగలదు."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"బ్యాక్గ్రౌండ్లో ఆడియోను రికార్డ్ చేయగలదు"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"మైక్రోఫోన్ను ఉపయోగించి ఈ యాప్ ఎప్పుడైనా ఆడియోను రికార్డ్ చేయగలదు."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"యాప్ విండోలకు సంబంధించిన స్క్రీన్ క్యాప్చర్లను గుర్తించండి"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"యాప్ ఉపయోగంలో ఉన్నప్పుడు స్క్రీన్షాట్ తీయబడినప్పుడు ఈ యాప్కు తెలియజేయబడుతుంది."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIMకి ఆదేశాలను పంపడం"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"సిమ్కు ఆదేశాలను పంపడానికి యాప్ను అనుమతిస్తుంది. ఇది చాలా ప్రమాదకరం."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"భౌతిక కార్యాకలాపాన్ని గుర్తించండి"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి ఫోన్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి టాబ్లెట్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string> <string name="vdm_secure_window" msgid="161700398158812314">"స్ట్రీమింగ్ చేస్తున్నప్పుడు దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ ఫోన్లో ట్రై చేయండి."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"స్ట్రీమింగ్ చేస్తున్నప్పుడు పిక్చర్-ఇన్-పిక్చర్ చూడలేరు"</string> <string name="system_locale_title" msgid="711882686834677268">"సిస్టమ్ ఆటోమేటిక్ సెట్టింగ్"</string> <string name="default_card_name" msgid="9198284935962911468">"కార్డ్ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 81c1d3927d1e..b5af3ded17da 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"อนุญาตให้แอปพลิเคชันทำให้ส่วนหนึ่งของตัวเองคงอยู่ถาวรในหน่วยความจำ ซึ่งจะจำกัดพื้นที่หน่วยความจำที่ใช้งานได้ของแอปพลิเคชันอื่นๆ และทำให้โทรศัพท์ทำงานช้าลง"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"เรียกใช้บริการที่ใช้งานอยู่"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ใช้งานอยู่"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"กล้อง\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"กล้อง\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"อุปกรณ์ที่เชื่อมต่อ\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"อุปกรณ์ที่เชื่อมต่อ\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การซิงค์ข้อมูล\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การซิงค์ข้อมูล\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"ตำแหน่ง\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"ตำแหน่ง\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การเล่นสื่อ\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การเล่นสื่อ\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การฉายภาพสื่อ\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การฉายภาพสื่อ\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"ไมโครโฟน\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"ไมโครโฟน\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การโทร\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การโทร\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"สุขภาพ\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"สุขภาพ\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การรับส่งข้อความระยะไกล\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การรับส่งข้อความระยะไกล\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"ได้รับการยกเว้นจากระบบ\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"ได้รับการยกเว้นจากระบบ\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การใช้งานพิเศษ\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"อนุญาตให้แอปใช้ประโยชน์จากบริการที่ทำงานอยู่เบื้องหน้าโดยมีประเภทเป็น \"การใช้งานพิเศษ\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"วัดพื้นที่เก็บข้อมูลของแอปพลิเคชัน"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"อนุญาตให้แอปพลิเคชันเรียกดูรหัส ข้อมูล และขนาดแคชของตน"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"แก้ไขการตั้งค่าระบบ"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 46783ead6cea..097abd6fbd19 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Pinapayagan ang app na panatilihin ang ilang bahagi nito sa memory. Maaari nitong limitahan ang memory na available sa iba pang apps na nagpapabagal sa telepono."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"paganahin ang foreground na serbisyo"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Payagan ang app na gamitin ang mga foreground na serbisyo."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"magpagana ng serbisyo sa foreground na may uring \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"magpagana ng serbisyo sa foreground na may uring \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"magpagana ng serbisyo sa foreground na may uring \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"magpagana ng serbisyo sa foreground na may uring \"lokasyon\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"lokasyon\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"magpagana ng serbisyo sa foreground na may uring \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"magpagana ng serbisyo sa foreground na may uring \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Nagbibigay-daan sa na gamitin ang mga serbisyo sa foreground na may uring \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"magpagana ng serbisyo sa foreground na may uring \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"magpagana ng serbisyo sa foreground gamit na may uring \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"magpagana ng serbisyo sa foreground na may uring \"kalusugan\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"kalusugan\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"magpagana ng serbisyo sa foreground na may uring \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"magpagana ng serbisyo sa foreground na may uring \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"magpagana ng serbisyo sa foreground na may uring \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Nagbibigay-daan sa app na gamitin ang mga serbisyo sa foreground na may uring \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"sukatin ang espasyo ng storage ng app"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Pinapayagan ang app na bawiin ang code, data, at mga laki ng cache nito"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"baguhin ang mga setting ng system"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Hindi ma-access ang camera ng telepono mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Hindi ma-access ang camera ng tablet mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Hindi ito puwedeng i-access habang nagsi-stream. Subukan na lang sa iyong telepono."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Hindi matingnan nang picture-in-picture habang nagsi-stream"</string> <string name="system_locale_title" msgid="711882686834677268">"Default ng system"</string> <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 87d7ba784345..4bf637a865b4 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Uygulamaya kendisinin bir bölümünü bellekte kalıcı yapma izni verir. Bu izin, diğer uygulamaların kullanabileceği belleği sınırlandırarak telefonun yavaş çalışmasına neden olabilir."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"ön plan hizmetini çalıştırma"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Uygulamanın ön plan hizmetlerinden faydalanmasına izin verir."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"camera\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Uygulamanın \"camera\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Uygulamanın \"connectedDevice\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Uygulamanın \"dataSync\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"location\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Uygulamanın \"location\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Uygulamanın \"mediaPlayback\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Uygulamanın \"mediaProjection\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"microphone\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Uygulamanın \"microphone\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Uygulamanın \"phoneCall\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"health\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Uygulamanın \"health\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Uygulamanın \"remoteMessaging\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Uygulamanın \"systemExempted\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" türüyle ön plan hizmetini çalıştırma"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Uygulamanın \"specialUse\" türüyle ön plan hizmetlerini kullanmasına izin verir"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"uygulama depolama alanını ölç"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Uygulamaya kodunu, verilerini ve önbellek boyutlarını alma izni verir"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"sistem ayarlarını değiştirme"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Bu uygulama, kullanıldığı sırada mikrofonu kullanarak ses kaydedebilir."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"arka planda ses kaydeder"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Bu uygulama, herhangi bir zaman mikrofonu kullanarak ses kaydedebilir."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"uygulama pencerelerindeki ekran görüntülerini algılama"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Uygulama kullanılırken ekran görüntüsü alındığında bu uygulama bilgilendirilir."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM karta komut gönderme"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Uygulamanın SIM karta komut göndermesine izin verir. Bu izin çok tehlikelidir."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"fiziksel aktiviteyi algıla"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına erişilemiyor"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan tabletin kamerasına erişilemiyor"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Canlı oynatılırken bu içeriğe erişilemez. Bunun yerine telefonunuzu kullanmayı deneyin."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Yayın sırasında pencere içinde pencere görüntülenemez"</string> <string name="system_locale_title" msgid="711882686834677268">"Sistem varsayılanı"</string> <string name="default_card_name" msgid="9198284935962911468">"KART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 7a815464c3a9..6e114dd349df 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -397,54 +397,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Дозволяє програмі робити свої частини сталими в пам’яті. Це може зменшувати обсяг пам’яті, доступної для інших програм, і сповільнювати роботу телефону."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"запускати пріоритетну службу"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Додаток може використовувати пріоритетні служби."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"запускати сервіс типу camera в активному режимі"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Дозволяє додатку використовувати активні сервіси типу camera"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"запускати сервіс типу connectedDevice в активному режимі"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Дозволяє додатку використовувати активні сервіси типу connectedDevice"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"запускати сервіс типу dataSync в активному режимі"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Дозволяє додатку використовувати активні сервіси типу dataSync"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"запускати сервіс типу location в активному режимі"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Дозволяє додатку використовувати активні сервіси типу location"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"запускати сервіс типу mediaPlayback в активному режимі"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Дозволяє додатку використовувати активні сервіси типу mediaPlayback"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"запускати сервіс типу mediaProjection в активному режимі"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Дозволяє додатку використовувати активні сервіси типу mediaProjection"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"запускати сервіс типу microphone в активному режимі"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Дозволяє додатку використовувати активні сервіси типу microphone"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"запускати сервіс типу phoneCall в активному режимі"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Дозволяє додатку використовувати активні сервіси типу phoneCall"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"запускати сервіс типу health в активному режимі"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Дозволяє додатку використовувати активні сервіси типу health"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"запускати сервіс типу remoteMessaging в активному режимі"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Дозволяє додатку використовувати активні сервіси типу remoteMessaging"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"запускати сервіс типу systemExempted в активному режимі"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Дозволяє додатку використовувати активні сервіси типу systemExempted"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"запускати сервіс типу specialUse в активному режимі"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Дозволяє додатку використовувати активні сервіси типу specialUse"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"визначати об’єм пам’яті програми"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Дозволяє програмі отримувати її код, дані та розміри кеш-пам’яті"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"змінювати налаштування системи"</string> @@ -497,10 +473,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Цей додаток може записувати звук за допомогою мікрофона, коли ви використовуєте його."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"записувати звук у фоновому режимі"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Цей додаток може будь-коли записувати звук за допомогою мікрофона."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"виявляти знімки екрана вікон додатка"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Цей додаток отримуватиме сповіщення, коли під час його роботи створюватимуться знімки екрана."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"надсилати команди на SIM-карту"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Дозволяє програмі надсилати команди на SIM-карту. Це дуже небезпечно."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"розпізнавати фізичну активність"</string> @@ -2344,8 +2318,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не вдається отримати доступ до камери телефона з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не вдається отримати доступ до камери планшета з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Цей контент недоступний під час потокового передавання. Спробуйте натомість скористатися телефоном."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Ви не можете переглядати картинку в картинці під час трансляції"</string> <string name="system_locale_title" msgid="711882686834677268">"Налаштування системи за умовчанням"</string> <string name="default_card_name" msgid="9198284935962911468">"КАРТКА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 69bf5e34a522..8afb2c8553a1 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"ایپ کو خود اپنے ہی حصوں کو میموری میں استقلال پذیر بنانے کی اجازت دیتا ہے۔ یہ فون کو سست بناکر دوسری ایپس کیلئے دستیاب میموری کو محدود کرسکتا ہے۔"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"پیش منظر سروس چلائیں"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"ایپ کو پیش منظر سروسز کے استعمال کی اجازت دیتا ہے۔"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"\"کیمرا\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"ایپ کو \"کیمرا\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"\"connectedDevice\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"ایپ کو \"connectedDevice\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"\"dataSync\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"ایپ کو \"dataSync\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"\"مقام\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"ایپ کو \"مقام\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"\"mediaPlayback\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"ایپ کو \"mediaPlayback\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"\"mediaProjection\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"ایپ کو \"mediaProjection\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"\"مائیکروفون\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"ایپ کو \"مائیکروفون\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"\"phoneCall\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"ایپ کو \"phoneCall\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"\"صحت\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"ایپ کو \"صحت\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"\"remoteMessaging\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"ایپ کو \"remoteMessaging\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"\"systemExempted\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"ایپ کو \"systemExempted\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"\"specialUse\" کی قسم کے ساتھ پیش منظر کی سروس چلائیں"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"ایپ کو \"specialUse\" کی قسم کے ساتھ پیش منظر کی سروسز کے استعمال کی اجازت دیتی ہے"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ایپ اسٹوریج کی جگہ کی پیمائش کریں"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"ایپ کو اپنے کوڈ، ڈیٹا اور کیش کے سائزوں کی بازیافت کرنے دیتا ہے"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"سسٹم کی ترتیبات میں ترمیم کریں"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"ایپ کے استعمال ہونے کے دوران یہ ایپ مائیکروفون استعمال کرتے ہوئے آڈیو ریکارڈ کر سکتی ہے۔"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"پس منظر میں آڈیو ریکارڈ کریں"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"یہ ایپ کسی بھی وقت مائیکروفون استعمال کرتے ہوئے آڈیو ریکارڈ کر سکتی ہے۔"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"ایپ کی ونڈوز کے اسکرین کیپچرز کا پتہ لگائیں"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"اس ایپ کے استعمال کے دوران اسکرین شاٹ لینے پر اس ایپ کو مطلع کیا جائے گا۔"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"SIM کو ہدایات بھیجیں"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"ایپ کو SIM کو کمانڈز بھیجنے کی اجازت دیتا ہے۔ یہ بہت خطرناک ہے۔"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"جسمانی سرگرمی کی شناخت کریں"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے فون کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے ٹیبلیٹ کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string> <string name="vdm_secure_window" msgid="161700398158812314">"سلسلہ بندی کے دوران اس تک رسائی حاصل نہیں کی جا سکتی۔ اس کے بجائے اپنے فون پر کوشش کریں۔"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"سلسلہ بندی کے دوران تصویر میں تصویر نہیں دیکھ سکتے"</string> <string name="system_locale_title" msgid="711882686834677268">"سسٹم ڈیفالٹ"</string> <string name="default_card_name" msgid="9198284935962911468">"کارڈ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index c5e6f57f714f..984981db2140 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Ilovaga o‘zining komponentlarini xotirada doimiy saqlashga ruxsat beradi. Bu mavjud xotirani cheklashi va telefonni sekin ishlashiga sabab bo‘lishi mumkin."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"faol xizmatlarni ishga tushirish"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Ilovaga faol xizmatlardan foydalanishga ruxsat beradi."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"“camera” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Ilovaga “camera” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"“connectedDevice” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Ilovaga “connectedDevice” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"“dataSync” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Ilovaga “dataSync” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"“location” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Ilovaga “location” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"“mediaPlayback” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Ilovaga “mediaPlayback” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"“mediaProjection” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Ilovaga “mediaProjection” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"“microphone” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Ilovaga “microphone” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"“phoneCall” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Ilovaga “phoneCall” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"“health” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Ilovaga “health” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"“remoteMessaging” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Ilovaga “remoteMessaging” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"“systemExempted” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Ilovaga “systemExempted” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"“specialUse” turidagi faol xizmatni ishga tushirish"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Ilovaga “specialUse” turidagi faol xizmatlardan foydalanishga ruxsat beradi"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"ilovalar egallagan xotira joyini hisoblash"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Ilova o‘zining kodi, ma’lumotlari va kesh o‘lchami to‘g‘risidagi ma’lumotlarni olishi mumkin"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"tizim sozlamalarini o‘zgartirish"</string> @@ -2340,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan telefonning kamerasiga kirish imkonsiz"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan planshetning kamerasiga kirish imkonsiz"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Bu kontent striming vaqtida ochilmaydi. Telefon orqali urininb koʻring."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Striming vaqtida tasvir ustida tasvir rejimida koʻrib boʻlmaydi"</string> <string name="system_locale_title" msgid="711882686834677268">"Tizim standarti"</string> <string name="default_card_name" msgid="9198284935962911468">"SIM KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index ed0e98a1a241..4e2dcebd1c63 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Cho phép ứng dụng tạo sự đồng nhất cho các phần của mình trong bộ nhớ. Việc này có thể hạn chế bộ nhớ đối với các ứng dụng khác đang làm chậm điện thoại."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"chạy dịch vụ trên nền trước"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Cho phép ứng dụng sử dụng các dịch vụ trên nền trước."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"chạy dịch vụ trên nền trước thuộc loại \"camera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"camera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"chạy dịch vụ trên nền trước thuộc loại \"connectedDevice\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"chạy dịch vụ trên nền trước thuộc loại \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"chạy dịch vụ trên nền trước thuộc loại \"location\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"location\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"chạy dịch vụ trên nền trước thuộc loại \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"chạy dịch vụ trên nền trước thuộc loại \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"chạy dịch vụ trên nền trước thuộc loại \"microphone\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"microphone\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"chạy dịch vụ trên nền trước thuộc loại \"phoneCall\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"chạy dịch vụ trên nền trước thuộc loại \"health\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"health\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"chạy dịch vụ trên nền trước thuộc loại \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"chạy dịch vụ trên nền trước thuộc loại \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"chạy dịch vụ trên nền trước thuộc loại \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Cho phép ứng dụng dùng các dịch vụ trên nền trước thuộc loại \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"đo dung lượng lưu trữ ứng dụng"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Cho phép ứng dụng truy xuất mã, dữ liệu và kích thước bộ nhớ đệm của chính ứng dụng"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"sửa đổi các chế độ cài đặt hệ thống"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ứng dụng này có thể ghi âm bằng micrô khi bạn đang dùng ứng dụng."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ghi âm trong nền"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ứng dụng này có thể ghi âm bằng micrô bất kỳ lúc nào."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"phát hiện ảnh chụp màn hình các cửa sổ ứng dụng"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Ứng dụng này sẽ nhận được thông báo nếu người dùng chụp màn hình trong khi đang dùng ứng dụng."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"gửi lệnh đến SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Cho phép ứng dụng gửi lệnh đến SIM. Việc này rất nguy hiểm."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"nhận dạng hoạt động thể chất"</string> @@ -1262,7 +1236,7 @@ <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> tiếp tục dừng"</string> <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> tiếp tục dừng"</string> <string name="aerr_restart" msgid="2789618625210505419">"Mở lại ứng dụng"</string> - <string name="aerr_report" msgid="3095644466849299308">"Gửi phản hồi"</string> + <string name="aerr_report" msgid="3095644466849299308">"Gửi ý kiến phản hồi"</string> <string name="aerr_close" msgid="3398336821267021852">"Đóng"</string> <string name="aerr_mute" msgid="2304972923480211376">"Tắt tiếng cho đến khi thiết bị khởi động lại"</string> <string name="aerr_wait" msgid="3198677780474548217">"Đợi"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Không truy cập được vào máy ảnh trên điện thoại từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Không truy cập được vào máy ảnh trên máy tính bảng từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Bạn không thể truy cập vào nội dung này trong khi phát trực tuyến. Hãy thử trên điện thoại."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Không thể xem video ở chế độ hình trong hình khi đang truyền trực tuyến"</string> <string name="system_locale_title" msgid="711882686834677268">"Theo chế độ mặc định của hệ thống"</string> <string name="default_card_name" msgid="9198284935962911468">"THẺ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-watch/dimens_material.xml b/core/res/res/values-watch/dimens_material.xml index 82c088b679c5..51d401860f7f 100644 --- a/core/res/res/values-watch/dimens_material.xml +++ b/core/res/res/values-watch/dimens_material.xml @@ -45,6 +45,13 @@ <dimen name="progress_bar_size_medium">32dip</dimen> <dimen name="progress_bar_size_large">64dip</dimen> + <!-- Progress bar message dimens --> + <dimen name="message_progress_dialog_text_size">18sp</dimen> + <dimen name="message_progress_dialog_bottom_padding">80px</dimen> + <dimen name="message_progress_dialog_top_padding">0dp</dimen> + <dimen name="message_progress_dialog_start_padding">0dp</dimen> + <dimen name="message_progress_dialog_end_padding">0dp</dimen> + <!-- fallback for screen percentage widths --> <dimen name="screen_percentage_05">0dp</dimen> <dimen name="screen_percentage_10">0dp</dimen> diff --git a/core/res/res/values-watch/styles_material.xml b/core/res/res/values-watch/styles_material.xml index 5093aa8a5369..f34d9f9e97cd 100644 --- a/core/res/res/values-watch/styles_material.xml +++ b/core/res/res/values-watch/styles_material.xml @@ -97,4 +97,14 @@ please see styles_device_defaults.xml. <item name="gravity">center_horizontal|top</item> <item name="ellipsize">end</item> </style> + + <style name="ProgressDialogMessage"> + <item name="android:textAlignment">center</item> + <item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item> + <item name="textSize">@dimen/message_progress_dialog_text_size</item> + <item name="paddingBottom">@dimen/message_progress_dialog_bottom_padding</item> + <item name="paddingEnd">@dimen/message_progress_dialog_end_padding</item> + <item name="paddingStart">@dimen/message_progress_dialog_start_padding</item> + <item name="paddingTop">@dimen/message_progress_dialog_top_padding</item> + </style> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index f73900c81c26..d4bfe15724b8 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"允许该应用在内存中持续保留其自身的某些组件。这会限制其他应用可用的内存,从而减缓手机运行速度。"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"运行前台服务"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"允许该应用使用前台服务。"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"运行“camera”类型的前台服务"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"允许该应用使用“camera”类型的前台服务"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"运行“connectedDevice”类型的前台服务"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"允许该应用使用“connectedDevice”类型的前台服务"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"运行“dataSync”类型的前台服务"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"允许该应用使用“dataSync”类型的前台服务"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"运行“location”类型的前台服务"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"允许该应用使用“location”类型的前台服务"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"运行“mediaPlayback”类型的前台服务"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"允许该应用使用“mediaPlayback”类型的前台服务"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"运行“mediaProjection”类型的前台服务"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"允许该应用使用“mediaProjection”类型的前台服务"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"运行“microphone”类型的前台服务"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"允许该应用使用“microphone”类型的前台服务"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"运行“phoneCall”类型的前台服务"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"允许该应用使用“phoneCall”类型的前台服务"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"运行“health”类型的前台服务"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"允许该应用使用“health”类型的前台服务"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"运行“remoteMessaging”类型的前台服务"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"允许该应用使用“remoteMessaging”类型的前台服务"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"运行“systemExempted”类型的前台服务"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"允许该应用使用“systemExempted”类型的前台服务"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"运行“specialUse”类型的前台服务"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"允许该应用使用“specialUse”类型的前台服务"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"计算应用存储空间"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"允许应用检索其代码、数据和缓存大小"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"修改系统设置"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"当您使用此应用时,它可以使用麦克风录音。"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"在后台录音"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"此应用可以随时使用麦克风录音。"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"检测应用窗口的屏幕截图"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"在应用使用过程中截取屏幕截图时,此应用将收到通知。"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"向 SIM 卡发送命令"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"允许应用向SIM卡发送命令(此权限具有很高的危险性)。"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"识别身体活动"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问手机的摄像头"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问平板电脑的摄像头"</string> <string name="vdm_secure_window" msgid="161700398158812314">"流式传输时无法访问此内容。您可以尝试在手机上访问。"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"在线播放时无法查看画中画"</string> <string name="system_locale_title" msgid="711882686834677268">"系统默认设置"</string> <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 072ce463efc9..8344683e8590 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"允許應用程式設定本身的某些部分持續佔用記憶體。這樣可能會限制其他應用程式可用的記憶體,並拖慢手機的運作速度。"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"執行前景服務"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"允許應用程式使用前景服務。"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"配搭「camera」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"允許應用程式配搭「camera」類型使用前景服務"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"配搭「connectedDevice」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"允許應用程式配搭「connectedDevice」類型使用前景服務"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"配搭「dataSync」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"允許應用程式配搭「dataSync」類型使用前景服務"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"配搭「location」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"允許應用程式配搭「location」類型使用前景服務"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"配搭「mediaPlayback」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"允許應用程式配搭「mediaPlayback」類型使用前景服務"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"配搭「mediaProjection」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"允許應用程式配搭「mediaProjection」類型使用前景服務"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"配搭「microphone」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"允許應用程式配搭「microphone」類型使用前景服務"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"配搭「phoneCall」類型執行前景服務"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"允許應用程式配搭「phoneCall」類型使用前景服務"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"配搭「health」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"允許應用程式配搭「health」類型使用前景服務"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"配搭「remoteMessaging」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"允許應用程式配搭「remoteMessaging」類型使用前景服務"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"配搭「systemExempted」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"允許應用程式配搭「systemExempted」類型使用前景服務"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"配搭「specialUse」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"允許應用程式配搭「specialUse」類型使用前景服務"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"測量應用程式儲存空間"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"允許應用程式擷取本身的程式碼、資料和快取大小"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"修改系統設定"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"此應用程式在使用期間可使用麥克風錄音。"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"在背景錄音"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"此應用程式可隨時使用麥克風錄音。"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"偵測應用程式視窗是否擷取螢幕畫面"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"如有人在應用程式使用期間擷取螢幕截圖,此應用程式將會收到通知"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"發送指令至 SIM 卡"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"允許應用程式傳送指令到 SIM 卡。這項操作具有高危險性。"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"識別體能活動"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string> <string name="vdm_secure_window" msgid="161700398158812314">"串流播放時無法使用,請改用手機。"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"串流期間無法查看畫中畫"</string> <string name="system_locale_title" msgid="711882686834677268">"系統預設"</string> <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index f1b0f23d35cd..0f48935323cd 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"允許應用程式讓部分內容佔用記憶體,持續執行。這項設定可能會限制其他應用程式可用的記憶體,並拖慢手機運作速度。"</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"執行前景服務"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"允許應用程式使用前景服務。"</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"搭配「camera」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"允許應用程式搭配「camera」類型使用前景服務"</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"搭配「connectedDevice」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"允許應用程式搭配「connectedDevice」類型使用前景服務"</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"搭配「dataSync」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"允許應用程式搭配「dataSync」類型使用前景服務"</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"搭配「location」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"允許應用程式搭配「location」類型使用前景服務"</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"搭配「mediaPlayback」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"允許應用程式搭配「mediaPlayback」類型使用前景服務"</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"搭配「mediaProjection」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"允許應用程式搭配「mediaProjection」類型使用前景服務"</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"搭配「microphone」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"允許應用程式搭配「microphone」類型使用前景服務"</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"搭配「phoneCall」類型執行前景服務"</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"允許應用程式搭配「phoneCall」類型使用前景服務"</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"搭配「health」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"允許應用程式搭配「health」類型使用前景服務"</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"搭配「remoteMessaging」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"允許應用程式搭配「remoteMessaging」類型使用前景服務"</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"搭配「systemExempted」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"允許應用程式搭配「systemExempted」類型使用前景服務"</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"搭配「specialUse」類型執行前景服務"</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"允許應用程式搭配「specialUse」類型使用前景服務"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"測量應用程式儲存空間"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"允許應用程式擷取本身的程式碼、資料及快取大小"</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"修改系統設定"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"這個應用程式在使用期間可以使用麥克風錄音。"</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"在背景錄音"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"這個應用程式隨時可以使用麥克風錄音。"</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"偵測應用程式視窗是否擷取螢幕畫面"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"如果在使用應用程式過程中拍攝了螢幕截圖,這個應用程式將會收到通知。"</string> <string name="permlab_sim_communication" msgid="176788115994050692">"傳送指令到 SIM 卡"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"允許應用程式傳送指令到 SIM 卡。這麼做非常危險。"</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"辨識體能活動"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string> <string name="vdm_secure_window" msgid="161700398158812314">"串流播放時無法存取這項內容,請改用手機。"</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"串流播放時無法查看子母畫面"</string> <string name="system_locale_title" msgid="711882686834677268">"系統預設"</string> <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index c0a28746e2e4..cd8fcc764d39 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -395,54 +395,30 @@ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Ivumela uhlelo kusebenza ukwenza izingxenye yazo ezicindezelayo kumemori. Lokhu kungakhawulela imemori ekhona kwezinye izinhlelo zokusebenza ukwenza ukuthi ifoni ingasheshi."</string> <string name="permlab_foregroundService" msgid="1768855976818467491">"qalisa amasevisi waphambili"</string> <string name="permdesc_foregroundService" msgid="8720071450020922795">"Vumela uhlelo lokusebenza ukusebenzisa amasevisi wangaphambili."</string> - <!-- no translation found for permlab_foregroundServiceCamera (7814751737955715297) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceCamera (6973701931250595727) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceConnectedDevice (3019650546176872501) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceConnectedDevice (1067457315741352963) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceDataSync (5847463514326881076) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceDataSync (2267140263423973050) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceLocation (3745428302378535690) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceLocation (118894034365177183) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaPlayback (4002687983891935514) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaPlayback (3638032446063968043) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMediaProjection (2630868915733312527) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMediaProjection (4805677128082002298) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceMicrophone (7390033424890545399) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceMicrophone (1206041516173483201) --> - <skip /> - <!-- no translation found for permlab_foregroundServicePhoneCall (627937743867697892) --> - <skip /> - <!-- no translation found for permdesc_foregroundServicePhoneCall (5941660252587015147) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceHealth (3675776442080928184) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceHealth (2024586220562667185) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceRemoteMessaging (105670277002780950) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceRemoteMessaging (8767598075877576277) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSystemExempted (1597663713590612685) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSystemExempted (947381760834649622) --> - <skip /> - <!-- no translation found for permlab_foregroundServiceSpecialUse (7973536745876645082) --> - <skip /> - <!-- no translation found for permdesc_foregroundServiceSpecialUse (646713654541885919) --> - <skip /> + <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"qalisa isevisi ephambili ngohlobo lokuthi \"ikhamera\""</string> + <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"ikhamera\""</string> + <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"qalisa isevisi ephambili ngohlobo lokuthi \"Idivayisi exhunyiwe\""</string> + <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"connectedDevice\""</string> + <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"qalisa isevisi ephambili ngohlobo lokuthi \"dataSync\""</string> + <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"dataSync\""</string> + <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"qalisa isevisi ephambili ngohlobo lokuthi \"indawo\""</string> + <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Vumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"indawo\""</string> + <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"qalisa isevisi ephambili ngohlobo lokuthi \"mediaPlayback\""</string> + <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"mediaPlayback\""</string> + <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"qalisa isevisi ephambili ngohlobo lokuthi \"mediaProjection\""</string> + <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"mediaProjection\""</string> + <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"qalisa isevisi ephambili ngohlobo lokuthi \"imakrofoni\""</string> + <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"imakrofoni\""</string> + <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"qalisa isevisi ephambili ngohlobo lokuthi \"Ikholi yefoni\""</string> + <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"phoneCall\""</string> + <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"qalisa isevisi ephambili ngohlobo lokuthi \"impilo\""</string> + <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"impilo\""</string> + <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"qalisa isevisi ephambili ngohlobo lokuthi \"remoteMessaging\""</string> + <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"remoteMessaging\""</string> + <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"qalisa isevisi ephambili ngohlobo lokuthi \"systemExempted\""</string> + <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"systemExempted\""</string> + <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"qalisa isevisi ephambili ngohlobo lokuthi \"specialUse\""</string> + <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Kuvumela i-app ukusebenzisa amasevisi aphambili ngohlobo lokuthi \"specialUse\""</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"linganisa isikhala sokugcina uhlelo lokusebenza"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"Ivuela uhlelo lokusebenza ukuthi ithole kabusha ikhodi yayo, i-dat kanye nosayizi abagcinwe okwesikhashana."</string> <string name="permlab_writeSettings" msgid="8057285063719277394">"shintsha amasethingi esistimu"</string> @@ -495,10 +471,8 @@ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Lolu hlelo lokusebenza lungarekhoda umsindo lisebenzisa imakrofoni kuyilapho uhlelo lokusebenza lusetshenziswa."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"rekhoda umsindo ngemuva"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Lolu hlelo lokusebenza lungafunda umsindo lisebenzisa imakrofoni noma kunini."</string> - <!-- no translation found for permlab_detectScreenCapture (4447042362828799433) --> - <skip /> - <!-- no translation found for permdesc_detectScreenCapture (3485784917960342284) --> - <skip /> + <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"thola izithombe zesikrini zamawindi e-app"</string> + <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Loe-app izokwaziswa uma isithombe-skrini sithathwa ngenkathi i-app isetshenziswa."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"thumela imilayezo ku-SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Ivumela uhlelo lokusebenza ukuthumela imiyalo ku-SIM. Lokhu kuyingozi kakhulu."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"bona umsebenzi"</string> @@ -2342,8 +2316,7 @@ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ayikwazi ukufinyelela ikhamera yefoni kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ayikwazi ukufinyelela ikhamera yethebulethi kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string> <string name="vdm_secure_window" msgid="161700398158812314">"Lokhu akukwazi ukufinyelelwa ngenkathi usakaza. Zama efonini yakho kunalokho."</string> - <!-- no translation found for vdm_pip_blocked (4036107522497281397) --> - <skip /> + <string name="vdm_pip_blocked" msgid="4036107522497281397">"Ayikwazi ukubuka isithombe esiphakathi kwesithombe ngenkathi isakaza"</string> <string name="system_locale_title" msgid="711882686834677268">"Okuzenzakalelayo kwesistimu"</string> <string name="default_card_name" msgid="9198284935962911468">"IKHADI <xliff:g id="CARDNUMBER">%d</xliff:g>"</string> </resources> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index a5c082723046..6460007b52de 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1594,7 +1594,7 @@ {@link android.app.Service#startForeground(int, android.app.Notification, int)} with this type on devices running {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} is still allowed, but calling it with this type on devices running future platform - releases may get a {@link android.app.ForegroundServiceTypeNotAllowedException}. + releases may get a {@link android.app.InvalidForegroundServiceTypeException}. --> <flag name="dataSync" value="0x01" /> <!-- Music, video, news or other media play. diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index b92d96f53fbe..ccce9ba6a709 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -5354,6 +5354,12 @@ <bool name="config_cecRoutingControlDisabled_allowed">true</bool> <bool name="config_cecRoutingControlDisabled_default">true</bool> + <bool name="config_cecSoundbarMode_userConfigurable">true</bool> + <bool name="config_cecSoundbarModeEnabled_allowed">true</bool> + <bool name="config_cecSoundbarModeEnabled_default">false</bool> + <bool name="config_cecSoundbarModeDisabled_allowed">true</bool> + <bool name="config_cecSoundbarModeDisabled_default">true</bool> + <bool name="config_cecPowerControlMode_userConfigurable">true</bool> <bool name="config_cecPowerControlModeTv_allowed">true</bool> <bool name="config_cecPowerControlModeTv_default">false</bool> @@ -5539,6 +5545,13 @@ <bool name="config_cecQuerySadMaxDisabled_allowed">true</bool> <bool name="config_cecQuerySadMaxDisabled_default">false</bool> + <!-- eARC Configuration --> + <bool name="config_earcEnabled_userConfigurable">true</bool> + <bool name="config_earcFeatureEnabled_allowed">true</bool> + <bool name="config_earcFeatureEnabled_default">true</bool> + <bool name="config_earcFeatureDisabled_allowed">true</bool> + <bool name="config_earcFeatureDisabled_default">false</bool> + <!-- Whether app hibernation deletes OAT artifact files as part of global hibernation. --> <bool name="config_hibernationDeletesOatArtifactsEnabled">true</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9d7e6f8d2dc4..ae033cab0807 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -153,6 +153,7 @@ <java-symbol type="id" name="progress_horizontal" /> <java-symbol type="id" name="progress_number" /> <java-symbol type="id" name="progress_percent" /> + <java-symbol type="id" name="progress_dialog_message" /> <java-symbol type="id" name="progressContainer" /> <java-symbol type="id" name="rew" /> <java-symbol type="id" name="rightSpacer" /> @@ -4555,6 +4556,12 @@ <java-symbol type="bool" name="config_cecRoutingControlDisabled_allowed" /> <java-symbol type="bool" name="config_cecRoutingControlDisabled_default" /> + <java-symbol type="bool" name="config_cecSoundbarMode_userConfigurable" /> + <java-symbol type="bool" name="config_cecSoundbarModeEnabled_allowed" /> + <java-symbol type="bool" name="config_cecSoundbarModeEnabled_default" /> + <java-symbol type="bool" name="config_cecSoundbarModeDisabled_allowed" /> + <java-symbol type="bool" name="config_cecSoundbarModeDisabled_default" /> + <java-symbol type="bool" name="config_cecPowerControlMode_userConfigurable" /> <java-symbol type="bool" name="config_cecPowerControlModeTv_allowed" /> <java-symbol type="bool" name="config_cecPowerControlModeTv_default" /> @@ -4740,6 +4747,13 @@ <java-symbol type="bool" name="config_cecQuerySadMaxDisabled_allowed" /> <java-symbol type="bool" name="config_cecQuerySadMaxDisabled_default" /> + <!-- eARC Configuration --> + <java-symbol type="bool" name="config_earcEnabled_userConfigurable" /> + <java-symbol type="bool" name="config_earcFeatureEnabled_allowed" /> + <java-symbol type="bool" name="config_earcFeatureEnabled_default" /> + <java-symbol type="bool" name="config_earcFeatureDisabled_allowed" /> + <java-symbol type="bool" name="config_earcFeatureDisabled_default" /> + <!-- Ids for RemoteViews --> <java-symbol type="id" name="remote_views_next_child" /> <java-symbol type="id" name="remote_views_stable_id" /> diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java new file mode 100644 index 000000000000..a2d8467d2a67 --- /dev/null +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.broadcastradio; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; + +import static com.google.common.truth.Truth.assertWithMessage; + +import static org.mockito.Mockito.when; + +import android.app.ActivityManager; +import android.os.Binder; +import android.os.UserHandle; + +import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +/** + * Tests for {@link com.android.server.broadcastradio.RadioServiceUserController} + */ +public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTestCase { + + private static final int USER_ID_1 = 11; + private static final int USER_ID_2 = 12; + + @Mock + private UserHandle mUserHandleMock; + + @Override + protected void initializeSession(StaticMockitoSessionBuilder builder) { + builder.spyStatic(ActivityManager.class) + .spyStatic(Binder.class); + } + + @Before + public void setUp() { + doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); + doReturn(USER_ID_1).when(() -> ActivityManager.getCurrentUser()); + } + + @Test + public void isCurrentUser_forCurrentUser_returnsFalse() { + when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); + + assertWithMessage("Current user") + .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue(); + } + + @Test + public void isCurrentUser_forNonCurrentUser_returnsFalse() { + when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_2); + + assertWithMessage("Non-current user") + .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse(); + } + + @Test + public void isCurrentUser_forSystemUser_returnsTrue() { + when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM); + + assertWithMessage("System user") + .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue(); + } +} diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java index 93214e5a6944..36aa915a67ec 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java @@ -20,6 +20,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -28,6 +29,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.hardware.broadcastradio.IBroadcastRadio; +import android.hardware.radio.Announcement; +import android.hardware.radio.IAnnouncementListener; +import android.hardware.radio.ICloseHandle; import android.hardware.radio.ITuner; import android.hardware.radio.ITunerCallback; import android.hardware.radio.RadioManager; @@ -54,6 +58,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes private static final int DAB_RADIO_MODULE_ID = 1; private static final ArrayList<String> SERVICE_LIST = new ArrayList<>(Arrays.asList("FmService", "DabService")); + private static final int[] TEST_ENABLED_TYPES = new int[]{Announcement.TYPE_TRAFFIC}; private BroadcastRadioServiceImpl mBroadcastRadioService; private IBinder.DeathRecipient mFmDeathRecipient; @@ -78,6 +83,14 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes private TunerSession mFmTunerSessionMock; @Mock private ITunerCallback mTunerCallbackMock; + @Mock + private ICloseHandle mFmCloseHandleMock; + @Mock + private ICloseHandle mDabCloseHandleMock; + @Mock + private IAnnouncementListener mAnnouncementListenerMock; + @Mock + private IBinder mListenerBinderMock; @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { @@ -141,6 +154,19 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes } @Test + public void openSession_forNonCurrentUser_throwsException() throws Exception { + createBroadcastRadioService(); + doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + + IllegalStateException thrown = assertThrows(IllegalStateException.class, + () -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID, + /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock)); + + assertWithMessage("Exception for opening session by non-current user") + .that(thrown).hasMessageThat().contains("Cannot open session for non-current user"); + } + + @Test public void binderDied_forDeathRecipient() throws Exception { createBroadcastRadioService(); @@ -151,6 +177,22 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes .that(mBroadcastRadioService.hasModule(FM_RADIO_MODULE_ID)).isFalse(); } + @Test + public void addAnnouncementListener_addsOnAllRadioModules() throws Exception { + createBroadcastRadioService(); + when(mAnnouncementListenerMock.asBinder()).thenReturn(mListenerBinderMock); + when(mFmRadioModuleMock.addAnnouncementListener(any(), any())) + .thenReturn(mFmCloseHandleMock); + when(mDabRadioModuleMock.addAnnouncementListener(any(), any())) + .thenReturn(mDabCloseHandleMock); + + mBroadcastRadioService.addAnnouncementListener(TEST_ENABLED_TYPES, + mAnnouncementListenerMock); + + verify(mFmRadioModuleMock).addAnnouncementListener(any(), any()); + verify(mDabRadioModuleMock).addAnnouncementListener(any(), any()); + } + private void createBroadcastRadioService() throws RemoteException { doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); mockServiceManager(); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java index a29e9c5c9bb1..87d0ea473665 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java @@ -330,6 +330,20 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } @Test + public void tune_forCurrentUser_doesNotTune() throws Exception { + openAidlClients(/* numClients= */ 1); + doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); + RadioManager.ProgramInfo tuneInfo = + AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); + + mTunerSessions[0].tune(initialSel); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + .onCurrentProgramInfoChanged(tuneInfo); + } + + @Test public void step_withDirectionUp() throws Exception { long initFreq = AM_FM_FREQUENCY_LIST[1]; ProgramSelector initialSel = AidlTestUtils.makeFmSelector(initFreq); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java index 99e70436ac95..0b7bbeaab28e 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java @@ -156,6 +156,19 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes } @Test + public void openSession_forNonCurrentUser_throwsException() throws Exception { + createBroadcastRadioService(); + doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + + IllegalStateException thrown = assertThrows(IllegalStateException.class, + () -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID, + /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock)); + + assertWithMessage("Exception for opening session by non-current user") + .that(thrown).hasMessageThat().contains("Cannot open session for non-current user"); + } + + @Test public void addAnnouncementListener_addsOnAllRadioModules() throws Exception { createBroadcastRadioService(); when(mAnnouncementListenerMock.asBinder()).thenReturn(mBinderMock); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java index 8884053bb58c..b7da5d038f77 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java @@ -27,6 +27,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -337,6 +338,20 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { } @Test + public void tune_forCurrentUser_doesNotTune() throws Exception { + openAidlClients(/* numClients= */ 1); + doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); + RadioManager.ProgramInfo tuneInfo = + TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); + + mTunerSessions[0].tune(initialSel); + + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + .onCurrentProgramInfoChanged(tuneInfo); + } + + @Test public void step_withDirectionUp() throws Exception { long initFreq = AM_FM_FREQUENCY_LIST[1]; ProgramSelector initialSel = TestUtils.makeFmSelector(initFreq); @@ -427,6 +442,18 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { } @Test + public void cancel_forNonCurrentUser() throws Exception { + openAidlClients(/* numClients= */ 1); + ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); + mTunerSessions[0].tune(initialSel); + doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + + mTunerSessions[0].cancel(); + + verify(mHalTunerSessionMock, never()).cancel(); + } + + @Test public void getImage_withInvalidId_throwsIllegalArgumentException() throws Exception { openAidlClients(/* numClients= */ 1); int imageId = Constants.INVALID_IMAGE; diff --git a/core/tests/coretests/src/android/app/backup/BackupAgentTest.java b/core/tests/coretests/src/android/app/backup/BackupAgentTest.java index 4d5b0d2d4ae7..561c10bad015 100644 --- a/core/tests/coretests/src/android/app/backup/BackupAgentTest.java +++ b/core/tests/coretests/src/android/app/backup/BackupAgentTest.java @@ -21,7 +21,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; import android.app.backup.BackupAgent.IncludeExcludeRules; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; +import android.app.backup.BackupAnnotations.OperationType; import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags; import android.os.ParcelFileDescriptor; import android.os.UserHandle; @@ -66,7 +67,7 @@ public class BackupAgentTest { excludePaths.add(path); IncludeExcludeRules expectedRules = new IncludeExcludeRules(includePaths, excludePaths); - mBackupAgent = getAgentForOperationType(OperationType.BACKUP); + mBackupAgent = getAgentForBackupDestination(BackupDestination.CLOUD); when(mBackupScheme.maybeParseAndGetCanonicalExcludePaths()).thenReturn(excludePaths); when(mBackupScheme.maybeParseAndGetCanonicalIncludePaths()).thenReturn(includePaths); @@ -84,24 +85,26 @@ public class BackupAgentTest { @Test public void getBackupRestoreEventLogger_afterOnCreateForBackup_initializedForBackup() { BackupAgent agent = new TestFullBackupAgent(); - agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type + agent.onCreate(USER_HANDLE, BackupDestination.CLOUD, OperationType.BACKUP); - assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo(1); + assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo( + OperationType.BACKUP); } @Test public void getBackupRestoreEventLogger_afterOnCreateForRestore_initializedForRestore() { BackupAgent agent = new TestFullBackupAgent(); - agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type + agent.onCreate(USER_HANDLE, BackupDestination.CLOUD, OperationType.RESTORE); - assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo(1); + assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo( + OperationType.RESTORE); } @Test public void getBackupRestoreEventLogger_afterBackup_containsLogsLoggedByAgent() throws Exception { BackupAgent agent = new TestFullBackupAgent(); - agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type + agent.onCreate(USER_HANDLE, BackupDestination.CLOUD, OperationType.BACKUP); // TestFullBackupAgent logs DATA_TYPE_BACKED_UP when onFullBackup is called. agent.onFullBackup(new FullBackupDataOutput(/* quota = */ 0)); @@ -110,9 +113,9 @@ public class BackupAgentTest { .isEqualTo(DATA_TYPE_BACKED_UP); } - private BackupAgent getAgentForOperationType(@OperationType int operationType) { + private BackupAgent getAgentForBackupDestination(@BackupDestination int backupDestination) { BackupAgent agent = new TestFullBackupAgent(); - agent.onCreate(USER_HANDLE, operationType); + agent.onCreate(USER_HANDLE, backupDestination); return agent; } diff --git a/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java b/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java index b9fdc6d2aa23..112d39488ec1 100644 --- a/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java +++ b/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java @@ -16,8 +16,8 @@ package android.app.backup; -import static android.app.backup.BackupRestoreEventLogger.OperationType.BACKUP; -import static android.app.backup.BackupRestoreEventLogger.OperationType.RESTORE; +import static android.app.backup.BackupAnnotations.OperationType.BACKUP; +import static android.app.backup.BackupAnnotations.OperationType.RESTORE; import static com.google.common.truth.Truth.assertThat; diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java index 875cd0bb4e16..eead4edb6f90 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java @@ -16,9 +16,11 @@ package com.android.internal.app; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.Cursor; @@ -26,10 +28,12 @@ import android.graphics.Bitmap; import android.os.UserHandle; import android.util.Pair; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; import com.android.internal.app.chooser.TargetInfo; import com.android.internal.logging.MetricsLogger; -import java.util.List; import java.util.function.BiFunction; import java.util.function.Function; @@ -71,7 +75,10 @@ public class ChooserActivityOverrideData { public boolean isQuietModeEnabled; public boolean isWorkProfileUserRunning; public boolean isWorkProfileUserUnlocked; - public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; + public Integer myUserId; + public QuietModeManager mQuietModeManager; + public MyUserIdProvider mMyUserIdProvider; + public CrossProfileIntentsChecker mCrossProfileIntentsChecker; public PackageManager packageManager; public void reset() { @@ -95,14 +102,9 @@ public class ChooserActivityOverrideData { isQuietModeEnabled = false; isWorkProfileUserRunning = true; isWorkProfileUserUnlocked = true; + myUserId = null; packageManager = null; - multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { - @Override - public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, - int targetUserId) { - return hasCrossProfileIntents; - } - + mQuietModeManager = new QuietModeManager() { @Override public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { return isQuietModeEnabled; @@ -113,7 +115,27 @@ public class ChooserActivityOverrideData { UserHandle workProfileUserHandle) { isQuietModeEnabled = enabled; } + + @Override + public void markWorkProfileEnabledBroadcastReceived() { + } + + @Override + public boolean isWaitingToEnableWorkProfile() { + return false; + } }; + + mMyUserIdProvider = new MyUserIdProvider() { + @Override + public int getMyUserId() { + return myUserId != null ? myUserId : UserHandle.myUserId(); + } + }; + + mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class); + when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt())) + .thenAnswer(invocation -> hasCrossProfileIntents); } private ChooserActivityOverrideData() {} diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java new file mode 100644 index 000000000000..c6537c0fbfb3 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.action.ViewActions.swipeUp; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.NO_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.PERSONAL_PROFILE_ACCESS_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.PERSONAL_PROFILE_SHARE_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.WORK_PROFILE_ACCESS_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.ExpectedBlocker.WORK_PROFILE_SHARE_BLOCKER; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab.PERSONAL; +import static com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab.WORK; +import static com.android.internal.app.ChooserWrapperActivity.sOverrides; + +import static org.hamcrest.CoreMatchers.not; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.companion.DeviceFilter; +import android.content.Intent; +import android.os.UserHandle; + +import androidx.test.InstrumentationRegistry; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.rule.ActivityTestRule; + +import com.android.internal.R; +import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; +import com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +@DeviceFilter.MediumType +@RunWith(Parameterized.class) +public class ChooserActivityWorkProfileTest { + + private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry + .getInstrumentation().getTargetContext().getUser(); + private static final UserHandle WORK_USER_HANDLE = UserHandle.of(10); + + @Rule + public ActivityTestRule<ChooserWrapperActivity> mActivityRule = + new ActivityTestRule<>(ChooserWrapperActivity.class, false, + false); + private final TestCase mTestCase; + + public ChooserActivityWorkProfileTest(TestCase testCase) { + mTestCase = testCase; + } + + @Before + public void cleanOverrideData() { + sOverrides.reset(); + } + + @Test + public void testBlocker() { + setUpPersonalAndWorkComponentInfos(); + sOverrides.hasCrossProfileIntents = mTestCase.hasCrossProfileIntents(); + sOverrides.myUserId = mTestCase.getMyUserHandle().getIdentifier(); + + launchActivity(mTestCase.getIsSendAction()); + switchToTab(mTestCase.getTab()); + + switch (mTestCase.getExpectedBlocker()) { + case NO_BLOCKER: + assertNoBlockerDisplayed(); + break; + case PERSONAL_PROFILE_SHARE_BLOCKER: + assertCantSharePersonalAppsBlockerDisplayed(); + break; + case WORK_PROFILE_SHARE_BLOCKER: + assertCantShareWorkAppsBlockerDisplayed(); + break; + case PERSONAL_PROFILE_ACCESS_BLOCKER: + assertCantAccessPersonalAppsBlockerDisplayed(); + break; + case WORK_PROFILE_ACCESS_BLOCKER: + assertCantAccessWorkAppsBlockerDisplayed(); + break; + } + } + + @Parameterized.Parameters(name = "{0}") + public static Collection tests() { + return Arrays.asList( + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), +// TODO(b/256869196) ChooserActivity goes into requestLayout loop +// new TestCase( +// /* isSendAction= */ true, +// /* hasCrossProfileIntents= */ false, +// /* myUserHandle= */ WORK_USER_HANDLE, +// /* tab= */ WORK, +// /* expectedBlocker= */ NO_BLOCKER +// ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ WORK_PROFILE_SHARE_BLOCKER + ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), +// TODO(b/256869196) ChooserActivity goes into requestLayout loop +// new TestCase( +// /* isSendAction= */ true, +// /* hasCrossProfileIntents= */ false, +// /* myUserHandle= */ WORK_USER_HANDLE, +// /* tab= */ PERSONAL, +// /* expectedBlocker= */ PERSONAL_PROFILE_SHARE_BLOCKER +// ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ true, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ WORK_PROFILE_ACCESS_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ PERSONAL_PROFILE_ACCESS_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* isSendAction= */ false, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ) + ); + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile( + int numberOfResults, int userId) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add( + ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId)); + } + return infoList; + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add(ResolverDataProvider.createResolvedComponentInfo(i)); + } + return infoList; + } + + private void setUpPersonalAndWorkComponentInfos() { + // enable the work tab feature flag + ResolverActivity.ENABLE_TABBED_VIEW = true; + markWorkProfileUserAvailable(); + int workProfileTargets = 4; + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(3, + /* userId */ WORK_USER_HANDLE.getIdentifier()); + List<ResolvedComponentInfo> workResolvedComponentInfos = + createResolvedComponentsForTest(workProfileTargets); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); + } + + private void setupResolverControllers( + List<ResolvedComponentInfo> personalResolvedComponentInfos, + List<ResolvedComponentInfo> workResolvedComponentInfos) { + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + } + + private void waitForIdle() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } + + private void markWorkProfileUserAvailable() { + ChooserWrapperActivity.sOverrides.workProfileUserHandle = WORK_USER_HANDLE; + } + + private void assertCantAccessWorkAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_work_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantAccessPersonalAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_personal_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantShareWorkAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_share_with_work_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantSharePersonalAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_share_with_personal_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertNoBlockerDisplayed() { + try { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(not(isDisplayed()))); + } catch (NoMatchingViewException ignored) { + } + } + + private void switchToTab(Tab tab) { + final int stringId = tab == Tab.WORK ? R.string.resolver_work_tab + : R.string.resolver_personal_tab; + + onView(withText(stringId)).perform(click()); + waitForIdle(); + + onView(withId(R.id.contentPanel)) + .perform(swipeUp()); + waitForIdle(); + } + + private Intent createTextIntent(boolean isSendAction) { + Intent sendIntent = new Intent(); + if (isSendAction) { + sendIntent.setAction(Intent.ACTION_SEND); + } + sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending"); + sendIntent.setType("text/plain"); + return sendIntent; + } + + private void launchActivity(boolean isSendAction) { + Intent sendIntent = createTextIntent(isSendAction); + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "Test")); + waitForIdle(); + } + + public static class TestCase { + private final boolean mIsSendAction; + private final boolean mHasCrossProfileIntents; + private final UserHandle mMyUserHandle; + private final Tab mTab; + private final ExpectedBlocker mExpectedBlocker; + + public enum ExpectedBlocker { + NO_BLOCKER, + PERSONAL_PROFILE_SHARE_BLOCKER, + WORK_PROFILE_SHARE_BLOCKER, + PERSONAL_PROFILE_ACCESS_BLOCKER, + WORK_PROFILE_ACCESS_BLOCKER + } + + public enum Tab { + WORK, + PERSONAL + } + + public TestCase(boolean isSendAction, boolean hasCrossProfileIntents, + UserHandle myUserHandle, Tab tab, ExpectedBlocker expectedBlocker) { + mIsSendAction = isSendAction; + mHasCrossProfileIntents = hasCrossProfileIntents; + mMyUserHandle = myUserHandle; + mTab = tab; + mExpectedBlocker = expectedBlocker; + } + + public boolean getIsSendAction() { + return mIsSendAction; + } + + public boolean hasCrossProfileIntents() { + return mHasCrossProfileIntents; + } + + public UserHandle getMyUserHandle() { + return mMyUserHandle; + } + + public Tab getTab() { + return mTab; + } + + public ExpectedBlocker getExpectedBlocker() { + return mExpectedBlocker; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("test"); + + if (mTab == WORK) { + result.append("WorkTab_"); + } else { + result.append("PersonalTab_"); + } + + if (mIsSendAction) { + result.append("sendAction_"); + } else { + result.append("notSendAction_"); + } + + if (mHasCrossProfileIntents) { + result.append("hasCrossProfileIntents_"); + } else { + result.append("doesNotHaveCrossProfileIntents_"); + } + + if (mMyUserHandle.equals(PERSONAL_USER_HANDLE)) { + result.append("myUserIsPersonal_"); + } else { + result.append("myUserIsWork_"); + } + + if (mExpectedBlocker == ExpectedBlocker.NO_BLOCKER) { + result.append("thenNoBlocker"); + } else if (mExpectedBlocker == PERSONAL_PROFILE_ACCESS_BLOCKER) { + result.append("thenAccessBlockerOnPersonalProfile"); + } else if (mExpectedBlocker == PERSONAL_PROFILE_SHARE_BLOCKER) { + result.append("thenShareBlockerOnPersonalProfile"); + } else if (mExpectedBlocker == WORK_PROFILE_ACCESS_BLOCKER) { + result.append("thenAccessBlockerOnWorkProfile"); + } else if (mExpectedBlocker == WORK_PROFILE_SHARE_BLOCKER) { + result.append("thenShareBlockerOnWorkProfile"); + } + + return result.toString(); + } + } +} 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 4c3235ca8ac0..5dc0c8b24218 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -16,6 +16,10 @@ package com.android.internal.app; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.annotation.Nullable; @@ -34,6 +38,8 @@ import android.os.UserHandle; import android.util.Pair; import android.util.Size; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; @@ -60,15 +66,6 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW } @Override - protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( - Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { - AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = - super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); - multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); - return multiProfilePagerAdapter; - } - - @Override public ChooserListAdapter createChooserListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, ResolverListController resolverListController) { @@ -135,6 +132,30 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW } @Override + protected MyUserIdProvider createMyUserIdProvider() { + if (sOverrides.mMyUserIdProvider != null) { + return sOverrides.mMyUserIdProvider; + } + return super.createMyUserIdProvider(); + } + + @Override + protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { + if (sOverrides.mCrossProfileIntentsChecker != null) { + return sOverrides.mCrossProfileIntentsChecker; + } + return super.createCrossProfileIntentsChecker(); + } + + @Override + protected AbstractMultiProfilePagerAdapter.QuietModeManager createQuietModeManager() { + if (sOverrides.mQuietModeManager != null) { + return sOverrides.mQuietModeManager; + } + return super.createQuietModeManager(); + } + + @Override public void safelyStartActivity(com.android.internal.app.chooser.TargetInfo cti) { if (sOverrides.onSafelyStartCallback != null && sOverrides.onSafelyStartCallback.apply(cti)) { diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java new file mode 100644 index 000000000000..ce68906a5bff --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.action.ViewActions.swipeUp; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.ExpectedBlocker.NO_BLOCKER; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.ExpectedBlocker.PERSONAL_PROFILE_BLOCKER; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.ExpectedBlocker.WORK_PROFILE_BLOCKER; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.Tab.PERSONAL; +import static com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.Tab.WORK; +import static com.android.internal.app.ResolverWrapperActivity.sOverrides; + +import static org.hamcrest.CoreMatchers.not; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.annotation.Nullable; +import android.companion.DeviceFilter; +import android.content.Intent; +import android.os.UserHandle; + +import androidx.test.InstrumentationRegistry; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.rule.ActivityTestRule; + +import com.android.internal.R; +import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; +import com.android.internal.app.ResolverActivityWorkProfileTest.TestCase.Tab; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +@DeviceFilter.MediumType +@RunWith(Parameterized.class) +public class ResolverActivityWorkProfileTest { + + private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry + .getInstrumentation().getTargetContext().getUser(); + private static final UserHandle WORK_USER_HANDLE = UserHandle.of(10); + + @Rule + public ActivityTestRule<ResolverWrapperActivity> mActivityRule = + new ActivityTestRule<>(ResolverWrapperActivity.class, false, + false); + private final TestCase mTestCase; + + public ResolverActivityWorkProfileTest(TestCase testCase) { + mTestCase = testCase; + } + + @Before + public void cleanOverrideData() { + sOverrides.reset(); + } + + @Test + public void testBlocker() { + setUpPersonalAndWorkComponentInfos(); + sOverrides.hasCrossProfileIntents = mTestCase.hasCrossProfileIntents(); + sOverrides.myUserId = mTestCase.getMyUserHandle().getIdentifier(); + + launchActivity(/* callingUser= */ mTestCase.getExtraCallingUser()); + switchToTab(mTestCase.getTab()); + + switch (mTestCase.getExpectedBlocker()) { + case NO_BLOCKER: + assertNoBlockerDisplayed(); + break; + case PERSONAL_PROFILE_BLOCKER: + assertCantAccessPersonalAppsBlockerDisplayed(); + break; + case WORK_PROFILE_BLOCKER: + assertCantAccessWorkAppsBlockerDisplayed(); + break; + } + } + + @Parameterized.Parameters(name = "{0}") + public static Collection tests() { + return Arrays.asList( + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ WORK_PROFILE_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ PERSONAL_PROFILE_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ null, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ WORK, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ WORK_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ true, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ), + new TestCase( + /* extraCallingUser= */ WORK_USER_HANDLE, + /* hasCrossProfileIntents= */ false, + /* myUserHandle= */ PERSONAL_USER_HANDLE, + /* tab= */ PERSONAL, + /* expectedBlocker= */ NO_BLOCKER + ) + ); + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile( + int numberOfResults, int userId) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add( + ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId)); + } + return infoList; + } + + private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) { + List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults); + for (int i = 0; i < numberOfResults; i++) { + infoList.add(ResolverDataProvider.createResolvedComponentInfo(i)); + } + return infoList; + } + + private void setUpPersonalAndWorkComponentInfos() { + // enable the work tab feature flag + ResolverActivity.ENABLE_TABBED_VIEW = true; + markWorkProfileUserAvailable(); + int workProfileTargets = 4; + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(3, + /* userId */ WORK_USER_HANDLE.getIdentifier()); + List<ResolvedComponentInfo> workResolvedComponentInfos = + createResolvedComponentsForTest(workProfileTargets); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); + } + + private void setupResolverControllers( + List<ResolvedComponentInfo> personalResolvedComponentInfos, + List<ResolvedComponentInfo> workResolvedComponentInfos) { + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))) + .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + } + + private void waitForIdle() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } + + private void markWorkProfileUserAvailable() { + ResolverWrapperActivity.sOverrides.workProfileUserHandle = WORK_USER_HANDLE; + } + + private void assertCantAccessWorkAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_work_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertCantAccessPersonalAppsBlockerDisplayed() { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(isDisplayed())); + onView(withText(R.string.resolver_cant_access_personal_apps_explanation)) + .check(matches(isDisplayed())); + } + + private void assertNoBlockerDisplayed() { + try { + onView(withText(R.string.resolver_cross_profile_blocked)) + .check(matches(not(isDisplayed()))); + } catch (NoMatchingViewException ignored) { + } + } + + private void switchToTab(Tab tab) { + final int stringId = tab == Tab.WORK ? R.string.resolver_work_tab + : R.string.resolver_personal_tab; + + onView(withText(stringId)).perform(click()); + waitForIdle(); + + onView(withId(R.id.contentPanel)) + .perform(swipeUp()); + waitForIdle(); + } + + private Intent createSendImageIntent() { + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending"); + sendIntent.setType("image/jpeg"); + return sendIntent; + } + + private void launchActivity(UserHandle callingUser) { + Intent sendIntent = createSendImageIntent(); + sendIntent.setType("TestType"); + + if (callingUser != null) { + sendIntent.putExtra(ResolverActivity.EXTRA_CALLING_USER, callingUser); + } + + mActivityRule.launchActivity(sendIntent); + waitForIdle(); + } + + public static class TestCase { + @Nullable + private final UserHandle mExtraCallingUser; + private final boolean mHasCrossProfileIntents; + private final UserHandle mMyUserHandle; + private final Tab mTab; + private final ExpectedBlocker mExpectedBlocker; + + public enum ExpectedBlocker { + NO_BLOCKER, + PERSONAL_PROFILE_BLOCKER, + WORK_PROFILE_BLOCKER + } + + public enum Tab { + WORK, + PERSONAL + } + + public TestCase(@Nullable UserHandle extraCallingUser, boolean hasCrossProfileIntents, + UserHandle myUserHandle, Tab tab, ExpectedBlocker expectedBlocker) { + mExtraCallingUser = extraCallingUser; + mHasCrossProfileIntents = hasCrossProfileIntents; + mMyUserHandle = myUserHandle; + mTab = tab; + mExpectedBlocker = expectedBlocker; + } + + @Nullable + public UserHandle getExtraCallingUser() { + return mExtraCallingUser; + } + + public boolean hasCrossProfileIntents() { + return mHasCrossProfileIntents; + } + + public UserHandle getMyUserHandle() { + return mMyUserHandle; + } + + public Tab getTab() { + return mTab; + } + + public ExpectedBlocker getExpectedBlocker() { + return mExpectedBlocker; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("test"); + + if (mTab == WORK) { + result.append("WorkTab_"); + } else { + result.append("PersonalTab_"); + } + + if (mExtraCallingUser != null + && !mExtraCallingUser.equals(PERSONAL_USER_HANDLE)) { + result.append("callingUserIsNonPersonal_"); + } else { + result.append("callingUserIsPersonal_"); + } + + if (mHasCrossProfileIntents) { + result.append("hasCrossProfileIntents_"); + } else { + result.append("doesNotHaveCrossProfileIntents_"); + } + + if (mMyUserHandle.equals(PERSONAL_USER_HANDLE)) { + result.append("myUserIsPersonal_"); + } else { + result.append("myUserIsWork_"); + } + + if (mExpectedBlocker == ExpectedBlocker.NO_BLOCKER) { + result.append("thenNoBlocker"); + } else if (mExpectedBlocker == ExpectedBlocker.PERSONAL_PROFILE_BLOCKER) { + result.append("thenBlockerOnPersonalProfile"); + } else if (mExpectedBlocker == WORK_PROFILE_BLOCKER) { + result.append("thenBlockerOnWorkProfile"); + } + + return result.toString(); + } + } +} diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java index 4cf9c3fe75b9..c778dfeaf376 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java @@ -16,6 +16,8 @@ package com.android.internal.app; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -27,6 +29,9 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.os.UserHandle; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; +import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; import com.android.internal.app.chooser.TargetInfo; import java.util.List; @@ -52,12 +57,27 @@ public class ResolverWrapperActivity extends ResolverActivity { } @Override - protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( - Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { - AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = - super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); - multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); - return multiProfilePagerAdapter; + protected MyUserIdProvider createMyUserIdProvider() { + if (sOverrides.mMyUserIdProvider != null) { + return sOverrides.mMyUserIdProvider; + } + return super.createMyUserIdProvider(); + } + + @Override + protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { + if (sOverrides.mCrossProfileIntentsChecker != null) { + return sOverrides.mCrossProfileIntentsChecker; + } + return super.createCrossProfileIntentsChecker(); + } + + @Override + protected QuietModeManager createQuietModeManager() { + if (sOverrides.mQuietModeManager != null) { + return sOverrides.mQuietModeManager; + } + return super.createQuietModeManager(); } ResolverWrapperAdapter getAdapter() { @@ -137,9 +157,12 @@ public class ResolverWrapperActivity extends ResolverActivity { public ResolverListController workResolverListController; public Boolean isVoiceInteraction; public UserHandle workProfileUserHandle; + public Integer myUserId; public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; - public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; + public QuietModeManager mQuietModeManager; + public MyUserIdProvider mMyUserIdProvider; + public CrossProfileIntentsChecker mCrossProfileIntentsChecker; public void reset() { onSafelyStartCallback = null; @@ -148,15 +171,11 @@ public class ResolverWrapperActivity extends ResolverActivity { resolverListController = mock(ResolverListController.class); workResolverListController = mock(ResolverListController.class); workProfileUserHandle = null; + myUserId = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; - multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { - @Override - public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, - int targetUserId) { - return hasCrossProfileIntents; - } + mQuietModeManager = new QuietModeManager() { @Override public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { return isQuietModeEnabled; @@ -167,7 +186,27 @@ public class ResolverWrapperActivity extends ResolverActivity { UserHandle workProfileUserHandle) { isQuietModeEnabled = enabled; } + + @Override + public void markWorkProfileEnabledBroadcastReceived() { + } + + @Override + public boolean isWaitingToEnableWorkProfile() { + return false; + } }; + + mMyUserIdProvider = new MyUserIdProvider() { + @Override + public int getMyUserId() { + return myUserId != null ? myUserId : UserHandle.myUserId(); + } + }; + + mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class); + when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt())) + .thenAnswer(invocation -> hasCrossProfileIntents); } } } diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp new file mode 100644 index 000000000000..82998dbdae27 --- /dev/null +++ b/core/tests/overlaytests/device_self_targeting/Android.bp @@ -0,0 +1,39 @@ +// Copyright (C) 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "SelfTargetingOverlayDeviceTests", + srcs: ["src/**/*.java"], + platform_apis: true, + static_libs: [ + "androidx.test.rules", + "androidx.test.runner", + "androidx.test.ext.junit", + "truth-prebuilt", + ], + + optimize: { + enabled: false, + }, + test_suites: ["device-tests"], +} diff --git a/core/tests/overlaytests/device_self_targeting/AndroidManifest.xml b/core/tests/overlaytests/device_self_targeting/AndroidManifest.xml new file mode 100644 index 000000000000..c121bf28fa7a --- /dev/null +++ b/core/tests/overlaytests/device_self_targeting/AndroidManifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.overlaytest.self_targeting"> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.overlaytest.self_targeting" + android:label="Self-Targeting resource overlay tests" /> +</manifest> diff --git a/core/tests/overlaytests/device_self_targeting/res/drawable/mydrawable.webp b/core/tests/overlaytests/device_self_targeting/res/drawable/mydrawable.webp Binary files differnew file mode 100644 index 000000000000..aa7d6427e6fa --- /dev/null +++ b/core/tests/overlaytests/device_self_targeting/res/drawable/mydrawable.webp diff --git a/core/tests/overlaytests/device_self_targeting/res/raw/overlay_drawable.webp b/core/tests/overlaytests/device_self_targeting/res/raw/overlay_drawable.webp Binary files differnew file mode 100644 index 000000000000..9126ae37cbc3 --- /dev/null +++ b/core/tests/overlaytests/device_self_targeting/res/raw/overlay_drawable.webp diff --git a/core/tests/overlaytests/device_self_targeting/res/values/values.xml b/core/tests/overlaytests/device_self_targeting/res/values/values.xml new file mode 100644 index 000000000000..f0b4a6fe8969 --- /dev/null +++ b/core/tests/overlaytests/device_self_targeting/res/values/values.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources> + <color name="mycolor">#ff112233</color> + <string name="mystring">hello</string> +</resources> diff --git a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java new file mode 100644 index 000000000000..ca584106a910 --- /dev/null +++ b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.overlaytest; + +import static android.content.Context.MODE_PRIVATE; + +import static com.android.internal.content.om.OverlayManagerImpl.SELF_TARGET; + +import static org.junit.Assert.assertThrows; + +import android.annotation.NonNull; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.om.OverlayInfo; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.os.FabricatedOverlayInternal; +import android.os.FabricatedOverlayInternalEntry; +import android.os.ParcelFileDescriptor; +import android.os.UserHandle; +import android.util.Log; +import android.util.Pair; +import android.util.TypedValue; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.internal.content.om.OverlayManagerImpl; +import com.android.overlaytest.self_targeting.R; + +import com.google.common.truth.Expect; +import com.google.common.truth.Truth; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; + +/** + * This test class verify the interfaces of {@link + * com.android.internal.content.om.OverlayManagerImpl}. + */ +@RunWith(AndroidJUnit4.class) +public class OverlayManagerImplTest { + private static final String TAG = "OverlayManagerImplTest"; + + private static final String TARGET_COLOR_RES = "color/mycolor"; + private static final String TARGET_STRING_RES = "string/mystring"; + private static final String TARGET_DRAWABLE_RES = "drawable/mydrawable"; + + private Context mContext; + private OverlayManagerImpl mOverlayManagerImpl; + private String mOverlayName; + + @Rule public TestName mTestName = new TestName(); + + @Rule public Expect expect = Expect.create(); + + private void clearDir() throws IOException { + final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + final Path basePath = context.getDir(SELF_TARGET, MODE_PRIVATE).toPath(); + Files.walkFileTree( + basePath, + new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + if (!file.toFile().delete()) { + Log.w(TAG, "Failed to delete file " + file); + } + return super.visitFile(file, attrs); + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) + throws IOException { + if (!dir.toFile().delete()) { + Log.w(TAG, "Failed to delete dir " + dir); + } + return super.postVisitDirectory(dir, exc); + } + }); + } + + @Before + public void setUp() throws IOException { + clearDir(); + mOverlayName = mTestName.getMethodName(); + mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + mOverlayManagerImpl = new OverlayManagerImpl(mContext); + } + + @After + public void tearDown() throws IOException { + clearDir(); + } + + private <T> void addOverlayEntry( + FabricatedOverlayInternal overlayInternal, + @NonNull List<Pair<String, Pair<String, T>>> entryDefinitions) { + List<FabricatedOverlayInternalEntry> entries = new ArrayList<>(); + for (Pair<String, Pair<String, T>> entryDefinition : entryDefinitions) { + FabricatedOverlayInternalEntry internalEntry = new FabricatedOverlayInternalEntry(); + internalEntry.resourceName = entryDefinition.first; + internalEntry.configuration = entryDefinition.second.first; + if (entryDefinition.second.second instanceof ParcelFileDescriptor) { + internalEntry.binaryData = (ParcelFileDescriptor) entryDefinition.second.second; + } else if (entryDefinition.second.second instanceof String) { + internalEntry.stringData = (String) entryDefinition.second.second; + internalEntry.dataType = TypedValue.TYPE_STRING; + } else { + internalEntry.data = (int) entryDefinition.second.second; + internalEntry.dataType = TypedValue.TYPE_INT_COLOR_ARGB8; + } + entries.add(internalEntry); + overlayInternal.entries = entries; + } + } + + private <T> FabricatedOverlayInternal createOverlayWithName( + @NonNull String overlayName, + @NonNull String targetPackageName, + @NonNull List<Pair<String, Pair<String, T>>> entryDefinitions) { + final String packageName = mContext.getPackageName(); + FabricatedOverlayInternal overlayInternal = new FabricatedOverlayInternal(); + overlayInternal.overlayName = overlayName; + overlayInternal.targetPackageName = targetPackageName; + overlayInternal.packageName = packageName; + + addOverlayEntry(overlayInternal, entryDefinitions); + + return overlayInternal; + } + + @Test + public void registerOverlay_forAndroidPackage_shouldFail() { + FabricatedOverlayInternal overlayInternal = + createOverlayWithName( + mOverlayName, + "android", + List.of(Pair.create("color/white", Pair.create(null, Color.BLACK)))); + + assertThrows( + "Wrong target package name", + IllegalArgumentException.class, + () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal)); + } + + @Test + public void getOverlayInfosForTarget_defaultShouldBeZero() { + List<OverlayInfo> overlayInfos = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()); + + Truth.assertThat(overlayInfos.size()).isEqualTo(0); + } + + @Test + public void unregisterNonExistingOverlay_shouldBeOk() { + mOverlayManagerImpl.unregisterFabricatedOverlay("NotExisting"); + } + + @Test + public void registerOverlay_createColorOverlay_shouldBeSavedInAndLoadFromFile() + throws IOException, PackageManager.NameNotFoundException { + FabricatedOverlayInternal overlayInternal = + createOverlayWithName( + mOverlayName, + mContext.getPackageName(), + List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE)))); + + mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal); + final List<OverlayInfo> overlayInfos = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()); + + final int firstNumberOfOverlays = overlayInfos.size(); + expect.that(firstNumberOfOverlays).isEqualTo(1); + final OverlayInfo overlayInfo = overlayInfos.get(0); + expect.that(overlayInfo).isNotNull(); + Truth.assertThat(expect.hasFailures()).isFalse(); + expect.that(overlayInfo.isFabricated()).isTrue(); + expect.that(overlayInfo.getOverlayName()).isEqualTo(mOverlayName); + expect.that(overlayInfo.getPackageName()).isEqualTo(mContext.getPackageName()); + expect.that(overlayInfo.getTargetPackageName()).isEqualTo(mContext.getPackageName()); + expect.that(overlayInfo.getUserId()).isEqualTo(mContext.getUserId()); + } + + @Test + public void registerOverlay_createStringOverlay_shouldBeSavedInAndLoadFromFile() + throws IOException, PackageManager.NameNotFoundException { + FabricatedOverlayInternal overlayInternal = + createOverlayWithName( + mOverlayName, + mContext.getPackageName(), + List.of(Pair.create(TARGET_STRING_RES, Pair.create(null, "HELLO")))); + + mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal); + final List<OverlayInfo> overlayInfos = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()); + + final int firstNumberOfOverlays = overlayInfos.size(); + expect.that(firstNumberOfOverlays).isEqualTo(1); + final OverlayInfo overlayInfo = overlayInfos.get(0); + expect.that(overlayInfo).isNotNull(); + Truth.assertThat(expect.hasFailures()).isFalse(); + expect.that(overlayInfo.isFabricated()).isTrue(); + expect.that(overlayInfo.getOverlayName()).isEqualTo(mOverlayName); + expect.that(overlayInfo.getPackageName()).isEqualTo(mContext.getPackageName()); + expect.that(overlayInfo.getTargetPackageName()).isEqualTo(mContext.getPackageName()); + expect.that(overlayInfo.getUserId()).isEqualTo(mContext.getUserId()); + } + + @Test + public void registerOverlay_createFileOverlay_shouldBeSavedInAndLoadFromFile() + throws IOException, PackageManager.NameNotFoundException { + ParcelFileDescriptor parcelFileDescriptor = mContext.getResources() + .openRawResourceFd(R.raw.overlay_drawable).getParcelFileDescriptor(); + FabricatedOverlayInternal overlayInternal = + createOverlayWithName( + mOverlayName, + mContext.getPackageName(), + List.of(Pair.create(TARGET_DRAWABLE_RES, + Pair.create(null, parcelFileDescriptor)))); + + mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal); + final List<OverlayInfo> overlayInfos = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()); + + final int firstNumberOfOverlays = overlayInfos.size(); + expect.that(firstNumberOfOverlays).isEqualTo(1); + final OverlayInfo overlayInfo = overlayInfos.get(0); + expect.that(overlayInfo).isNotNull(); + Truth.assertThat(expect.hasFailures()).isFalse(); + expect.that(overlayInfo.isFabricated()).isTrue(); + expect.that(overlayInfo.getOverlayName()).isEqualTo(mOverlayName); + expect.that(overlayInfo.getPackageName()).isEqualTo(mContext.getPackageName()); + expect.that(overlayInfo.getTargetPackageName()).isEqualTo(mContext.getPackageName()); + expect.that(overlayInfo.getUserId()).isEqualTo(mContext.getUserId()); + } + + @Test + public void registerOverlay_notExistedResource_shouldFailWithoutSavingAnyFile() + throws IOException { + FabricatedOverlayInternal overlayInternal = + createOverlayWithName( + mOverlayName, + mContext.getPackageName(), + List.of(Pair.create("color/not_existed", Pair.create(null, "HELLO")))); + + assertThrows(IOException.class, + () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal)); + final List<OverlayInfo> overlayInfos = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()); + final int firstNumberOfOverlays = overlayInfos.size(); + expect.that(firstNumberOfOverlays).isEqualTo(0); + final int[] fileCounts = new int[1]; + Files.walkFileTree( + mContext.getDir(SELF_TARGET, MODE_PRIVATE).toPath(), + new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + fileCounts[0]++; + return super.visitFile(file, attrs); + } + }); + expect.that(fileCounts[0]).isEqualTo(0); + } + + @Test + public void registerMultipleOverlays_shouldMatchTheNumberOfOverlays() + throws IOException, PackageManager.NameNotFoundException { + final String secondOverlayName = mOverlayName + "2nd"; + final int initNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + + FabricatedOverlayInternal overlayInternal = + createOverlayWithName( + mOverlayName, + mContext.getPackageName(), + List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE)))); + mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal); + final int firstNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + overlayInternal = + createOverlayWithName( + secondOverlayName, + mContext.getPackageName(), + List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE)))); + mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal); + final int secondNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + mOverlayManagerImpl.unregisterFabricatedOverlay(mOverlayName); + mOverlayManagerImpl.unregisterFabricatedOverlay(secondOverlayName); + final int finalNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + + expect.that(initNumberOfOverlays).isEqualTo(0); + expect.that(firstNumberOfOverlays).isEqualTo(1); + expect.that(secondNumberOfOverlays).isEqualTo(2); + expect.that(finalNumberOfOverlays).isEqualTo(0); + } + + @Test + public void unregisterOverlay_withIllegalOverlayName_shouldFail() { + assertThrows( + IllegalArgumentException.class, + () -> mOverlayManagerImpl.unregisterFabricatedOverlay("../../etc/password")); + } + + @Test + public void registerTheSameOverlay_shouldNotIncreaseTheNumberOfOverlays() + throws IOException, PackageManager.NameNotFoundException { + final int initNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + + FabricatedOverlayInternal overlayInternal = + createOverlayWithName( + mOverlayName, + mContext.getPackageName(), + List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE)))); + mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal); + final int firstNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + overlayInternal = + createOverlayWithName( + mOverlayName, + mContext.getPackageName(), + List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE)))); + mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal); + final int secondNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + mOverlayManagerImpl.unregisterFabricatedOverlay(mOverlayName); + final int finalNumberOfOverlays = + mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size(); + + expect.that(initNumberOfOverlays).isEqualTo(0); + expect.that(firstNumberOfOverlays).isEqualTo(1); + expect.that(secondNumberOfOverlays).isEqualTo(1); + expect.that(finalNumberOfOverlays).isEqualTo(0); + } + + @Test + public void registerOverlay_packageNotOwnedBySelf_shouldFail() { + FabricatedOverlayInternal overlayInternal = new FabricatedOverlayInternal(); + overlayInternal.packageName = "com.android.systemui"; + overlayInternal.overlayName = mOverlayName; + overlayInternal.targetOverlayable = "non-existed-target-overlayable"; + overlayInternal.targetPackageName = mContext.getPackageName(); + addOverlayEntry( + overlayInternal, + List.of(Pair.create("color/white", Pair.create(null, Color.BLACK)))); + + assertThrows( + "The context doesn't own the package", + IllegalArgumentException.class, + () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal)); + } + + @Test + public void ensureBaseDir_forOtherPackage_shouldFail() + throws PackageManager.NameNotFoundException { + final Context fakeContext = + mContext.createPackageContext("com.android.systemui", 0 /* flags */); + final OverlayManagerImpl overlayManagerImpl = new OverlayManagerImpl(fakeContext); + + assertThrows(IllegalArgumentException.class, overlayManagerImpl::ensureBaseDir); + } + + @Test + public void newOverlayManagerImpl_forOtherUser_shouldFail() { + Context fakeContext = + new ContextWrapper(mContext) { + @Override + public UserHandle getUser() { + return UserHandle.of(100); + } + + @Override + public int getUserId() { + return 100; + } + }; + + assertThrows(SecurityException.class, () -> new OverlayManagerImpl(fakeContext)); + } +} diff --git a/graphics/java/android/graphics/MeshSpecification.java b/graphics/java/android/graphics/MeshSpecification.java new file mode 100644 index 000000000000..b27c5e0ab728 --- /dev/null +++ b/graphics/java/android/graphics/MeshSpecification.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.annotation.IntDef; + +import libcore.util.NativeAllocationRegistry; + +/** + * Class responsible for holding specifications for {@link Mesh} creations. This class + * generates a {@link MeshSpecification} via the Make method, where multiple parameters to set up + * the mesh are supplied, including attributes, vertex stride, varyings, and + * vertex/fragment shaders. There are also additional methods to provide an optional + * {@link ColorSpace} as well as an alpha type. + * + * Note that there are several limitations on various mesh specifications: + * 1. The max amount of attributes allowed is 8. + * 2. The offset alignment length is 4 bytes. + * 2. The max stride length is 1024. + * 3. The max amount of varyings is 6. + * + * These should be kept in mind when generating a mesh specification, as exceeding them will + * lead to errors. + * + * @hide + */ +public class MeshSpecification { + private long mNativeMeshSpec; + + /** + * Constants for {@link #make(Attribute[], int, Varying[], String, String, ColorSpace, int)} + * to determine alpha type + */ + @IntDef({UNKNOWN, OPAQUE, PREMUL, UNPREMULT}) + public @interface AlphaType { + } + + public static final int UNKNOWN = 0; + public static final int OPAQUE = 1; + public static final int PREMUL = 2; + public static final int UNPREMULT = 3; + + /** + * Constants for {@link Attribute} and {@link Varying} for determining the data type. + */ + @IntDef({FLOAT, FLOAT2, FLOAT3, FLOAT4, UBYTE4}) + public @interface Type { + } + + public static final int FLOAT = 0; + public static final int FLOAT2 = 1; + public static final int FLOAT3 = 2; + public static final int FLOAT4 = 3; + public static final int UBYTE4 = 4; + + /** + * Data class to represent a single attribute in a shader. Note that type parameter must be + * one of {@link #FLOAT}, {@link #FLOAT2}, {@link #FLOAT3}, {@link #FLOAT4}, or {@link #UBYTE4}. + */ + public static class Attribute { + @Type + private int mType; + private int mOffset; + private String mName; + + public Attribute(@Type int type, int offset, String name) { + mType = type; + mOffset = offset; + mName = name; + } + } + + /** + * Data class to represent a single varying variable. Note that type parameter must be + * one of {@link #FLOAT}, {@link #FLOAT2}, {@link #FLOAT3}, {@link #FLOAT4}, or {@link #UBYTE4}. + */ + public static class Varying { + @Type + private int mType; + private String mName; + + public Varying(@Type int type, String name) { + mType = type; + mName = name; + } + } + + private static class MeshSpecificationHolder { + public static final NativeAllocationRegistry MESH_SPECIFICATION_REGISTRY = + NativeAllocationRegistry.createMalloced( + MeshSpecification.class.getClassLoader(), nativeGetFinalizer()); + } + + /** + * Creates a {@link MeshSpecification} object. + * + * @param attributes list of attributes represented by {@link Attribute}. Can hold a max of + * 8. + * @param vertexStride length of vertex stride. Max of 1024 is accepted. + * @param varyings List of varyings represented by {@link Varying}. Can hold a max of 6. + * @param vertexShader vertex shader to be supplied to the mesh. + * @param fragmentShader fragment shader to be suppied to the mesh. + * @return {@link MeshSpecification} object for use when creating {@link Mesh} + */ + public static MeshSpecification make(Attribute[] attributes, int vertexStride, + Varying[] varyings, String vertexShader, String fragmentShader) { + long nativeMeshSpec = + nativeMake(attributes, vertexStride, varyings, vertexShader, fragmentShader); + if (nativeMeshSpec == 0) { + throw new IllegalArgumentException("MeshSpecification construction failed"); + } + return new MeshSpecification(nativeMeshSpec); + } + + /** + * Creates a {@link MeshSpecification} object. + * + * @param attributes list of attributes represented by {@link Attribute}. Can hold a max of + * 8. + * @param vertexStride length of vertex stride. Max of 1024 is accepted. + * @param varyings List of varyings represented by {@link Varying}. Can hold a max of + * 6. + * @param vertexShader vertex shader to be supplied to the mesh. + * @param fragmentShader fragment shader to be supplied to the mesh. + * @param colorSpace {@link ColorSpace} to tell what color space to work in. + * @return {@link MeshSpecification} object for use when creating {@link Mesh} + */ + public static MeshSpecification make(Attribute[] attributes, int vertexStride, + Varying[] varyings, String vertexShader, String fragmentShader, ColorSpace colorSpace) { + long nativeMeshSpec = nativeMakeWithCS(attributes, vertexStride, varyings, vertexShader, + fragmentShader, colorSpace.getNativeInstance()); + if (nativeMeshSpec == 0) { + throw new IllegalArgumentException("MeshSpecification construction failed"); + } + return new MeshSpecification(nativeMeshSpec); + } + + /** + * Creates a {@link MeshSpecification} object. + * + * @param attributes list of attributes represented by {@link Attribute}. Can hold a max of + * 8. + * @param vertexStride length of vertex stride. Max of 1024 is accepted. + * @param varyings List of varyings represented by {@link Varying}. Can hold a max of 6. + * @param vertexShader vertex shader code to be supplied to the mesh. + * @param fragmentShader fragment shader code to be suppied to the mesh. + * @param colorSpace {@link ColorSpace} to tell what color space to work in. + * @param alphaType Describes how to interpret the alpha component for a pixel. Must be + * one of {@link AlphaType} values. + * @return {@link MeshSpecification} object for use when creating {@link Mesh} + */ + public static MeshSpecification make(Attribute[] attributes, int vertexStride, + Varying[] varyings, String vertexShader, String fragmentShader, ColorSpace colorSpace, + @AlphaType int alphaType) { + long nativeMeshSpec = nativeMakeWithAlpha(attributes, vertexStride, varyings, vertexShader, + fragmentShader, colorSpace.getNativeInstance(), alphaType); + if (nativeMeshSpec == 0) { + throw new IllegalArgumentException("MeshSpecification construction failed"); + } + return new MeshSpecification(nativeMeshSpec); + } + + private MeshSpecification(long meshSpec) { + mNativeMeshSpec = meshSpec; + MeshSpecificationHolder.MESH_SPECIFICATION_REGISTRY.registerNativeAllocation( + this, meshSpec); + } + + private static native long nativeGetFinalizer(); + + private static native long nativeMake(Attribute[] attributes, int vertexStride, + Varying[] varyings, String vertexShader, String fragmentShader); + + private static native long nativeMakeWithCS(Attribute[] attributes, int vertexStride, + Varying[] varyings, String vertexShader, String fragmentShader, long colorSpace); + + private static native long nativeMakeWithAlpha(Attribute[] attributes, int vertexStride, + Varying[] varyings, String vertexShader, String fragmentShader, long colorSpace, + int alphaType); +} diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java index 62455988db34..8c42547caea6 100644 --- a/keystore/java/android/security/keystore/KeyProperties.java +++ b/keystore/java/android/security/keystore/KeyProperties.java @@ -196,6 +196,7 @@ public abstract class KeyProperties { @StringDef(prefix = { "KEY_" }, value = { KEY_ALGORITHM_RSA, KEY_ALGORITHM_EC, + KEY_ALGORITHM_XDH, KEY_ALGORITHM_AES, KEY_ALGORITHM_HMAC_SHA1, KEY_ALGORITHM_HMAC_SHA224, @@ -211,6 +212,11 @@ public abstract class KeyProperties { /** Elliptic Curve (EC) Cryptography key. */ public static final String KEY_ALGORITHM_EC = "EC"; + /** Curve 25519 based Agreement key. + * @hide + */ + public static final String KEY_ALGORITHM_XDH = "XDH"; + /** Advanced Encryption Standard (AES) key. */ public static final String KEY_ALGORITHM_AES = "AES"; @@ -246,7 +252,8 @@ public abstract class KeyProperties { public static int toKeymasterAsymmetricKeyAlgorithm( @NonNull @KeyAlgorithmEnum String algorithm) { - if (KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) { + if (KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm) + || KEY_ALGORITHM_XDH.equalsIgnoreCase(algorithm)) { return KeymasterDefs.KM_ALGORITHM_EC; } else if (KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) { return KeymasterDefs.KM_ALGORITHM_RSA; diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java index 4e73bd9d3c82..4505eaf0c862 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java @@ -24,13 +24,9 @@ import android.system.keystore2.Authorization; import android.system.keystore2.KeyDescriptor; import android.system.keystore2.KeyMetadata; -import java.security.AlgorithmParameters; -import java.security.NoSuchAlgorithmException; import java.security.interfaces.ECPublicKey; -import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; -import java.security.spec.InvalidParameterSpecException; /** * {@link ECPublicKey} backed by keystore. @@ -62,34 +58,13 @@ public class AndroidKeyStoreECPublicKey extends AndroidKeyStorePublicKey impleme } } - private static String getEcCurveFromKeymaster(int ecCurve) { - switch (ecCurve) { - case android.hardware.security.keymint.EcCurve.P_224: - return "secp224r1"; - case android.hardware.security.keymint.EcCurve.P_256: - return "secp256r1"; - case android.hardware.security.keymint.EcCurve.P_384: - return "secp384r1"; - case android.hardware.security.keymint.EcCurve.P_521: - return "secp521r1"; - } - return ""; - } - - private ECParameterSpec getCurveSpec(String name) - throws NoSuchAlgorithmException, InvalidParameterSpecException { - AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC"); - parameters.init(new ECGenParameterSpec(name)); - return parameters.getParameterSpec(ECParameterSpec.class); - } - @Override public AndroidKeyStorePrivateKey getPrivateKey() { ECParameterSpec params = mParams; for (Authorization a : getAuthorizations()) { try { if (a.keyParameter.tag == KeymasterDefs.KM_TAG_EC_CURVE) { - params = getCurveSpec(getEcCurveFromKeymaster( + params = KeymasterUtils.getCurveSpec(KeymasterUtils.getEcCurveFromKeymaster( a.keyParameter.value.getEcCurve())); break; } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java index 4caa47f2078b..7292cd3c5fb1 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java @@ -32,7 +32,6 @@ import java.security.ProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.ECKey; -import java.security.interfaces.XECKey; import java.security.spec.AlgorithmParameterSpec; import java.util.ArrayList; import java.util.List; @@ -134,10 +133,15 @@ public class AndroidKeyStoreKeyAgreementSpi extends KeyAgreementSpi throw new InvalidKeyException("key == null"); } else if (!(key instanceof PublicKey)) { throw new InvalidKeyException("Only public keys supported. Key: " + key); - } else if (!(mKey instanceof ECKey && key instanceof ECKey) - && !(mKey instanceof XECKey && key instanceof XECKey)) { + } else if (mKey instanceof ECKey && !(key instanceof ECKey) + /*&& !(mKey instanceof XECKey && key instanceof XECKey)*/) { + /** TODO This condition is temporary modified, because OpenSSL implementation does not + * implement OpenSSLX25519PublicKey from XECKey interface (b/214203951). + * This change has to revert once conscrypt implements OpenSSLX25519PublicKey from + * XECKey interface. + */ throw new InvalidKeyException( - "Public and Private key should be of the same type:"); + "Public and Private key should be of the same type."); } else if (mKey instanceof ECKey && !((ECKey) key).getParams().getCurve() .equals(((ECKey) mKey).getParams().getCurve())) { diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index 7a320badb94e..2d609e8219eb 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -20,6 +20,7 @@ import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MG import android.annotation.NonNull; import android.hardware.biometrics.BiometricManager; +import android.hardware.security.keymint.EcCurve; import android.hardware.security.keymint.HardwareAuthenticatorType; import android.hardware.security.keymint.KeyParameter; import android.hardware.security.keymint.SecurityLevel; @@ -67,6 +68,14 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.ECKey; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.EdECKey; +import java.security.interfaces.EdECPrivateKey; +import java.security.interfaces.XECKey; +import java.security.interfaces.XECPrivateKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECParameterSpec; +import java.security.spec.NamedParameterSpec; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -567,22 +576,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { spec.getMaxUsageCount() )); } - if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(key.getAlgorithm())) { - if (key instanceof ECKey) { - ECKey ecKey = (ECKey) key; - importArgs.add(KeyStore2ParameterUtils.makeEnum( - KeymasterDefs.KM_TAG_EC_CURVE, - KeyProperties.EcCurve.toKeymasterCurve(ecKey.getParams()) - )); - } + if (KeymasterDefs.KM_ALGORITHM_EC + == KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm( + key.getAlgorithm())) { + importArgs.add(KeyStore2ParameterUtils.makeEnum( + KeymasterDefs.KM_TAG_EC_CURVE, + getKeymasterEcCurve(key) + )); } - /* TODO: check for Ed25519(EdDSA) or X25519(XDH) key algorithm and - * add import args for KM_TAG_EC_CURVE as EcCurve.CURVE_25519. - * Currently conscrypt does not support EdDSA key import and XDH keys are not an - * instance of XECKey, hence these conditions are not added, once it is fully - * implemented by conscrypt, we can add CURVE_25519 argument for EdDSA and XDH - * algorithms. - */ } catch (IllegalArgumentException | IllegalStateException e) { throw new KeyStoreException(e); } @@ -608,6 +609,31 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { } } + private int getKeymasterEcCurve(PrivateKey key) { + if (key instanceof ECKey) { + ECParameterSpec param = ((ECPrivateKey) key).getParams(); + int kmECCurve = KeymasterUtils.getKeymasterEcCurve(KeymasterUtils.getCurveName(param)); + if (kmECCurve >= 0) { + return kmECCurve; + } + } else if (key instanceof XECKey) { + AlgorithmParameterSpec param = ((XECPrivateKey) key).getParams(); + if (param.equals(NamedParameterSpec.X25519)) { + return EcCurve.CURVE_25519; + } + } else if (key.getAlgorithm().equals("XDH")) { + // TODO com.android.org.conscrypt.OpenSSLX25519PrivateKey does not implement XECKey, + // this case is not required once it implements XECKey interface(b/214203951). + return EcCurve.CURVE_25519; + } else if (key instanceof EdECKey) { + AlgorithmParameterSpec param = ((EdECPrivateKey) key).getParams(); + if (param.equals(NamedParameterSpec.ED25519)) { + return EcCurve.CURVE_25519; + } + } + throw new IllegalArgumentException("Unexpected Key " + key.getClass().getName()); + } + private static void assertCanReplace(String alias, @Domain int targetDomain, int targetNamespace, KeyDescriptor descriptor) throws KeyStoreException { diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java index 9f3df3d72d86..69138340f653 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java @@ -88,7 +88,7 @@ public class AndroidKeyStoreXDHPublicKey extends AndroidKeyStorePublicKey implem getUserKeyDescriptor(), getKeyIdDescriptor().nspace, getAuthorizations(), - "x25519", + "XDH", getSecurityLevel()); } diff --git a/keystore/java/android/security/keystore2/KeymasterUtils.java b/keystore/java/android/security/keystore2/KeymasterUtils.java index de4696cea3ac..614e3684c417 100644 --- a/keystore/java/android/security/keystore2/KeymasterUtils.java +++ b/keystore/java/android/security/keystore2/KeymasterUtils.java @@ -20,7 +20,12 @@ import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import android.security.keystore.KeyProperties; +import java.security.AlgorithmParameters; +import java.security.NoSuchAlgorithmException; import java.security.ProviderException; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.ECParameterSpec; +import java.security.spec.InvalidParameterSpecException; /** * @hide @@ -121,4 +126,65 @@ public abstract class KeymasterUtils { break; } } + + static String getEcCurveFromKeymaster(int ecCurve) { + switch (ecCurve) { + case android.hardware.security.keymint.EcCurve.P_224: + return "secp224r1"; + case android.hardware.security.keymint.EcCurve.P_256: + return "secp256r1"; + case android.hardware.security.keymint.EcCurve.P_384: + return "secp384r1"; + case android.hardware.security.keymint.EcCurve.P_521: + return "secp521r1"; + } + return ""; + } + + static int getKeymasterEcCurve(String ecCurveName) { + if (ecCurveName.equals("secp224r1")) { + return android.hardware.security.keymint.EcCurve.P_224; + } else if (ecCurveName.equals("secp256r1")) { + return android.hardware.security.keymint.EcCurve.P_256; + } else if (ecCurveName.equals("secp384r1")) { + return android.hardware.security.keymint.EcCurve.P_384; + } else if (ecCurveName.equals("secp521r1")) { + return android.hardware.security.keymint.EcCurve.P_521; + } + return -1; + } + + static ECParameterSpec getCurveSpec(String name) + throws NoSuchAlgorithmException, InvalidParameterSpecException { + AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC"); + parameters.init(new ECGenParameterSpec(name)); + return parameters.getParameterSpec(ECParameterSpec.class); + } + + static String getCurveName(ECParameterSpec spec) { + if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp224r1")) { + return "secp224r1"; + } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp256r1")) { + return "secp256r1"; + } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp384r1")) { + return "secp384r1"; + } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp521r1")) { + return "secp521r1"; + } + return null; + } + + private static boolean isECParameterSpecOfCurve(ECParameterSpec spec, String curveName) { + try { + ECParameterSpec curveSpec = KeymasterUtils.getCurveSpec(curveName); + if (curveSpec.getCurve().equals(spec.getCurve()) + && curveSpec.getOrder().equals(spec.getOrder()) + && curveSpec.getGenerator().equals(spec.getGenerator())) { + return true; + } + } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) { + return false; + } + return false; + } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index c06548ad81a1..4df2d7d82f6a 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -41,7 +41,6 @@ import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAs import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked; import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO; import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair; -import static androidx.window.extensions.embedding.SplitPresenter.getNonEmbeddedActivityBounds; import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSplit; import android.app.Activity; @@ -464,7 +463,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // parentInfo#isVisibleRequested is true. return; } - onTaskContainerInfoChanged(taskContainer, parentInfo.getConfiguration()); if (isInPictureInPicture(parentInfo.getConfiguration())) { // No need to update presentation in PIP until the Task exit PIP. return; @@ -614,12 +612,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } } - @GuardedBy("mLock") - private void onTaskContainerInfoChanged(@NonNull TaskContainer taskContainer, - @NonNull Configuration config) { - taskContainer.setTaskBounds(config.windowConfiguration.getBounds()); - } - /** Returns whether the given {@link TaskContainer} may show in split. */ // Suppress GuardedBy warning because lint asks to mark this method as // @GuardedBy(mPresenter.mController.mLock), which is mLock itself @@ -1235,13 +1227,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen final TaskContainer taskContainer = mTaskContainers.get(taskId); final TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity, pendingAppearedIntent, taskContainer, this); - if (!taskContainer.isTaskBoundsInitialized()) { - // Get the initial bounds before the TaskFragment has appeared. - final Rect taskBounds = getNonEmbeddedActivityBounds(activityInTask); - if (!taskContainer.setTaskBounds(taskBounds)) { - Log.w(TAG, "Can't find bounds from activity=" + activityInTask); - } - } return container; } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index f494b32cff14..5395fb2ef5ed 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -932,11 +932,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { if (taskContainer != null) { return taskContainer.getTaskProperties(); } - // Use a copy of configuration because activity's configuration may be updated later, - // or we may get unexpected TaskContainer's configuration if Activity's configuration is - // updated. An example is Activity is going to be in split. - return new TaskProperties(activity.getDisplayId(), - new Configuration(activity.getResources().getConfiguration())); + return TaskProperties.getTaskPropertiesFromActivity(activity); } @NonNull @@ -950,16 +946,4 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // TODO(b/190433398): Supply correct insets. return new WindowMetrics(taskBounds, WindowInsets.CONSUMED); } - - /** Obtains the bounds from a non-embedded Activity. */ - @NonNull - static Rect getNonEmbeddedActivityBounds(@NonNull Activity activity) { - final WindowConfiguration windowConfiguration = - activity.getResources().getConfiguration().windowConfiguration; - if (!activity.isInMultiWindowMode()) { - // In fullscreen mode the max bounds should correspond to the task bounds. - return windowConfiguration.getMaxBounds(); - } - return windowConfiguration.getBounds(); - } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java index 231da0542e95..dba5a7a1cf3c 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java @@ -20,14 +20,17 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.app.WindowConfiguration.inMultiWindowMode; import android.app.Activity; +import android.app.ActivityClient; import android.app.WindowConfiguration; import android.app.WindowConfiguration.WindowingMode; import android.content.res.Configuration; import android.graphics.Rect; import android.os.IBinder; import android.util.ArraySet; +import android.util.Log; import android.window.TaskFragmentInfo; import android.window.TaskFragmentParentInfo; import android.window.WindowContainerTransaction; @@ -41,14 +44,11 @@ import java.util.Set; /** Represents TaskFragments and split pairs below a Task. */ class TaskContainer { + private static final String TAG = TaskContainer.class.getSimpleName(); /** The unique task id. */ private final int mTaskId; - // TODO(b/240219484): consolidate to mConfiguration - /** Available window bounds of this Task. */ - private final Rect mTaskBounds = new Rect(); - /** Active TaskFragments in this Task. */ @NonNull final List<TaskFragmentContainer> mContainers = new ArrayList<>(); @@ -86,10 +86,10 @@ class TaskContainer { throw new IllegalArgumentException("Invalid Task id"); } mTaskId = taskId; - // Make a copy in case the activity's config is updated, and updates the TaskContainer's - // config unexpectedly. - mConfiguration = new Configuration(activityInTask.getResources().getConfiguration()); - mDisplayId = activityInTask.getDisplayId(); + final TaskProperties taskProperties = TaskProperties + .getTaskPropertiesFromActivity(activityInTask); + mConfiguration = taskProperties.getConfiguration(); + mDisplayId = taskProperties.getDisplayId(); // Note that it is always called when there's a new Activity is started, which implies // the host task is visible. mIsVisible = true; @@ -108,25 +108,6 @@ class TaskContainer { } @NonNull - Rect getTaskBounds() { - return mTaskBounds; - } - - /** Returns {@code true} if the bounds is changed. */ - boolean setTaskBounds(@NonNull Rect taskBounds) { - if (!taskBounds.isEmpty() && !mTaskBounds.equals(taskBounds)) { - mTaskBounds.set(taskBounds); - return true; - } - return false; - } - - /** Whether the Task bounds has been initialized. */ - boolean isTaskBoundsInitialized() { - return !mTaskBounds.isEmpty(); - } - - @NonNull Configuration getConfiguration() { // Make a copy in case the config is updated unexpectedly. return new Configuration(mConfiguration); @@ -261,5 +242,45 @@ class TaskContainer { Configuration getConfiguration() { return mConfiguration; } + + /** + * Obtains the {@link TaskProperties} for the task that the provided {@link Activity} is + * associated with. + * <p> + * Note that for most case, caller should use + * {@link SplitPresenter#getTaskProperties(Activity)} instead. This method is used before + * the {@code activity} goes into split. + * </p><p> + * If the {@link Activity} is in fullscreen, override + * {@link WindowConfiguration#getBounds()} with {@link WindowConfiguration#getMaxBounds()} + * in case the {@link Activity} is letterboxed. Otherwise, get the Task + * {@link Configuration} from the server side or use {@link Activity}'s + * {@link Configuration} as a fallback if the Task {@link Configuration} cannot be obtained. + */ + @NonNull + static TaskProperties getTaskPropertiesFromActivity(@NonNull Activity activity) { + final int displayId = activity.getDisplayId(); + // Use a copy of configuration because activity's configuration may be updated later, + // or we may get unexpected TaskContainer's configuration if Activity's configuration is + // updated. An example is Activity is going to be in split. + final Configuration activityConfig = new Configuration( + activity.getResources().getConfiguration()); + final WindowConfiguration windowConfiguration = activityConfig.windowConfiguration; + final int windowingMode = windowConfiguration.getWindowingMode(); + if (!inMultiWindowMode(windowingMode)) { + // Use the max bounds in fullscreen in case the Activity is letterboxed. + windowConfiguration.setBounds(windowConfiguration.getMaxBounds()); + return new TaskProperties(displayId, activityConfig); + } + final Configuration taskConfig = ActivityClient.getInstance() + .getTaskConfiguration(activity.getActivityToken()); + if (taskConfig == null) { + Log.w(TAG, "Could not obtain task configuration for activity:" + activity); + // Still report activity config if task config cannot be obtained from the server + // side. + return new TaskProperties(displayId, activityConfig); + } + return new TaskProperties(displayId, taskConfig); + } } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java index a7d47ef81687..13afa4910ae1 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java @@ -86,13 +86,23 @@ class TaskFragmentAnimationSpec { /** Animation for target that is opening in a change transition. */ @NonNull Animation createChangeBoundsOpenAnimation(@NonNull RemoteAnimationTarget target) { - final Rect bounds = target.localBounds; - // The target will be animated in from left or right depends on its position. - final int startLeft = bounds.left == 0 ? -bounds.width() : bounds.width(); + final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); + final Rect bounds = target.screenSpaceBounds; + final int startLeft; + final int startTop; + if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { + // The window will be animated in from left or right depending on its position. + startTop = 0; + startLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); + } else { + // The window will be animated in from top or bottom depending on its position. + startTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); + startLeft = 0; + } // The position should be 0-based as we will post translate in // TaskFragmentAnimationAdapter#onAnimationUpdate - final Animation animation = new TranslateAnimation(startLeft, 0, 0, 0); + final Animation animation = new TranslateAnimation(startLeft, 0, startTop, 0); animation.setInterpolator(mFastOutExtraSlowInInterpolator); animation.setDuration(CHANGE_ANIMATION_DURATION); animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height()); @@ -103,13 +113,24 @@ class TaskFragmentAnimationSpec { /** Animation for target that is closing in a change transition. */ @NonNull Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) { - final Rect bounds = target.localBounds; - // The target will be animated out to left or right depends on its position. - final int endLeft = bounds.left == 0 ? -bounds.width() : bounds.width(); + final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); + // TODO(b/258126915): we want to keep track of the closing start bounds + final Rect bounds = target.screenSpaceBounds; + final int endTop; + final int endLeft; + if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { + // The window will be animated out to left or right depending on its position. + endTop = 0; + endLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); + } else { + // The window will be animated out to top or bottom depending on its position. + endTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); + endLeft = 0; + } // The position should be 0-based as we will post translate in // TaskFragmentAnimationAdapter#onAnimationUpdate - final Animation animation = new TranslateAnimation(0, endLeft, 0, 0); + final Animation animation = new TranslateAnimation(0, endLeft, 0, endTop); animation.setInterpolator(mFastOutExtraSlowInInterpolator); animation.setDuration(CHANGE_ANIMATION_DURATION); animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height()); diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index 2192b5ca219c..b70b320eee3c 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -35,7 +35,6 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.util.ArrayMap; -import android.window.WindowContext; import android.window.WindowProvider; import androidx.annotation.NonNull; @@ -310,20 +309,21 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } final int windowingMode; if (context instanceof Activity) { - windowingMode = ActivityClient.getInstance().getTaskWindowingMode( + final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration( context.getActivityToken()); + if (taskConfig == null) { + // If we cannot determine the task configuration for any reason, it is likely that + // we won't be able to determine its position correctly as well. DisplayFeatures' + // bounds in this case can't be computed correctly, so we should skip. + return false; + } + windowingMode = taskConfig.windowConfiguration.getWindowingMode(); } else { // TODO(b/242674941): use task windowing mode for window context that associates with // activity. windowingMode = context.getResources().getConfiguration().windowConfiguration .getWindowingMode(); } - if (windowingMode == -1) { - // If we cannot determine the task windowing mode for any reason, it is likely that we - // won't be able to determine its position correctly as well. DisplayFeatures' bounds - // in this case can't be computed correctly, so we should skip. - return false; - } // It is recommended not to report any display features in multi-window mode, since it // won't be possible to synchronize the display feature positions with window movement. return !WindowConfiguration.inMultiWindowMode(windowingMode); diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java index 87d027899eb4..8c1b87a650e0 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java @@ -261,7 +261,7 @@ public class SplitControllerTest { assertNotNull(tf); assertNotNull(taskContainer); - assertEquals(TASK_BOUNDS, taskContainer.getTaskBounds()); + assertEquals(TASK_BOUNDS, taskContainer.getConfiguration().windowConfiguration.getBounds()); } @Test diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java index af9c6ba5c162..95328ce700e3 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java @@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; -import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS; import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTestTaskContainer; import static org.junit.Assert.assertEquals; @@ -68,28 +67,6 @@ public class TaskContainerTest { } @Test - public void testIsTaskBoundsInitialized() { - final TaskContainer taskContainer = createTestTaskContainer(); - - assertFalse(taskContainer.isTaskBoundsInitialized()); - - taskContainer.setTaskBounds(TASK_BOUNDS); - - assertTrue(taskContainer.isTaskBoundsInitialized()); - } - - @Test - public void testSetTaskBounds() { - final TaskContainer taskContainer = createTestTaskContainer(); - - assertFalse(taskContainer.setTaskBounds(new Rect())); - - assertTrue(taskContainer.setTaskBounds(TASK_BOUNDS)); - - assertFalse(taskContainer.setTaskBounds(TASK_BOUNDS)); - } - - @Test public void testGetWindowingModeForSplitTaskFragment() { final TaskContainer taskContainer = createTestTaskContainer(); final Rect splitBounds = new Rect(0, 0, 500, 1000); diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 42da07571679..27c245c12f3e 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Laat los"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Program sal dalk nie met verdeelde skerm werk nie."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Program steun nie verdeelde skerm nie."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Program steun nie begin op sekondêre skerms nie."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skermverdeler"</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index ef53c9548862..0248719e3036 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string> <string name="accessibility_divider" msgid="703810061635792791">"የተከፈለ የማያ ገጽ ከፋይ"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index f5ea409f8002..cc7df4a35bdf 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"إظهار"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"قد لا يعمل التطبيق بشكل سليم في وضع \"تقسيم الشاشة\"."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"التطبيق لا يتيح تقسيم الشاشة."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string> <string name="accessibility_divider" msgid="703810061635792791">"أداة تقسيم الشاشة"</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index c4cfcf778665..aafcfe7aa145 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"দেখুৱাওক"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"এপ্টোৱে বিভাজিত স্ক্ৰীনৰ সৈতে কাম নকৰিব পাৰে।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"এপ্টোৱে বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"গৌণ ডিছপ্লেত এপে সঠিকভাৱে কাম নকৰিব পাৰে।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"গৌণ ডিছপ্লেত এপ্ লঞ্চ কৰিব নোৱাৰি।"</string> <string name="accessibility_divider" msgid="703810061635792791">"স্প্লিট স্ক্ৰীনৰ বিভাজক"</string> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 84f706af3a76..d4b5bad840cf 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Güvənli məkandan çıxarın"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Tətbiq bölünmüş ekran ilə işləməyə bilər."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Tətbiq ekran bölünməsini dəstəkləmir."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Tətbiq ikinci ekranda işləməyə bilər."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcısı"</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index 2eb1ac284bb0..c2ee13bd14d5 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Uklonite iz tajne memorije"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće raditi sa podeljenim ekranom."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava podeljeni ekran."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdelnik podeljenog ekrana"</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index b6ce7851812e..ea205efe20a8 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Паказаць"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Праграма можа не працаваць у рэжыме падзеленага экрана."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Праграма не падтрымлівае функцыю дзялення экрана."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Праграма можа не працаваць на дадатковых экранах."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Праграма не падтрымлівае запуск на дадатковых экранах."</string> <string name="accessibility_divider" msgid="703810061635792791">"Раздзяляльнік падзеленага экрана"</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index ce2291482692..f91dda0e3c04 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Отмяна на съхраняването"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Приложението може да не работи в режим на разделен екран."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Приложението не поддържа разделен екран."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Възможно е приложението да не работи на алтернативни дисплеи."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложението не поддържа използването на алтернативни дисплеи."</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделител в режима за разделен екран"</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 52ae816e9639..0cc798ca548d 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"আনস্ট্যাস করুন"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"অ্যাপটি স্প্লিট স্ক্রিনে কাজ নাও করতে পারে।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"অ্যাপ্লিকেশান বিভক্ত-স্ক্রিন সমর্থন করে না৷"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"সেকেন্ডারি ডিসপ্লেতে অ্যাপটি কাজ নাও করতে পারে।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"সেকেন্ডারি ডিসপ্লেতে অ্যাপ লঞ্চ করা যাবে না।"</string> <string name="accessibility_divider" msgid="703810061635792791">"বিভক্ত-স্ক্রিন বিভাজক"</string> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index e7ff6b62d11c..e235179f5472 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Vađenje iz stasha"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće raditi na podijeljenom ekranu."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava dijeljenje ekrana."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće raditi na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog ekrana"</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 43c8badd0f95..30b8d090291c 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Deixa d\'amagar"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"L\'aplicació no admet la pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'aplicació no es pot obrir en pantalles secundàries."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalles"</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index 0d68e4696fad..b78e93adaf00 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zrušit uložení"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikace v režimu rozdělené obrazovky nemusí fungovat."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikace nepodporuje režim rozdělené obrazovky."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikace na sekundárním displeji nemusí fungovat."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikace nepodporuje spuštění na sekundárních displejích."</string> <string name="accessibility_divider" msgid="703810061635792791">"Čára rozdělující obrazovku"</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 28c00644f6e8..1544099dd5aa 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Vis"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Appen fungerer muligvis ikke i opdelt skærm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Appen understøtter ikke opdelt skærm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer muligvis ikke på sekundære skærme."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke åbnes på sekundære skærme."</string> <string name="accessibility_divider" msgid="703810061635792791">"Adskiller til opdelt skærm"</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index 41af26d8525c..9a4b20eb4d3a 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Aus Stash entfernen"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Die App funktioniert unter Umständen im Modus für geteilten Bildschirm nicht."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Das Teilen des Bildschirms wird in dieser App nicht unterstützt."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Die App unterstützt den Start auf sekundären Displays nicht."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bildschirmteiler"</string> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index 3e08ee1f2ab3..8aca81eb8129 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Κατάργηση απόκρυψης"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Η εφαρμογή ενδέχεται να μην λειτουργεί με διαχωρισμό οθόνης."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string> <string name="accessibility_divider" msgid="703810061635792791">"Διαχωριστικό οθόνης"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 231c26497982..ec44597c7414 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 431c7eccecdd..91875c5ffbe8 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split-screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index 231c26497982..ec44597c7414 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 231c26497982..ec44597c7414 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index f3e60d2c1595..ace138787570 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"App may not work with split-screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App does not support split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split-screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index fe29baa5a55e..704e696e59db 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Dejar de almacenar de manera segura"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Es posible que la app no funcione en el modo de pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"La app no es compatible con la función de pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la app no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La app no puede iniciarse en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 8f20e162a00b..2ad8b53732bc 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"No esconder"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Es posible que la aplicación no funcione con la pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"La aplicación no admite la pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la aplicación no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La aplicación no se puede abrir en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Dividir la pantalla"</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 698e5ccb562f..359a06d49696 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Eemalda hoidlast"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Rakendus ei pruugi poolitatud ekraaniga töötada."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Rakendus ei toeta jagatud ekraani."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Rakendus ei pruugi teisesel ekraanil töötada."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekraanijagaja"</string> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 629c74554753..f3e9b8f3a384 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ez gorde"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikazioak ez du onartzen pantaila zatitua"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pantaila-zatitzailea"</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index b7920ef1847e..58f221e32ddb 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"لغو مخفیسازی"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ممکن است برنامه با «صفحهٔ دونیمه» کار نکند."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"برنامه از تقسیم صفحه پشتیبانی نمیکند."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن است برنامه در نمایشگر ثانویه کار نکند."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"برنامه از راهاندازی در نمایشگرهای ثانویه پشتیبانی نمیکند."</string> <string name="accessibility_divider" msgid="703810061635792791">"تقسیمکننده صفحه"</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 18def679afe5..191a21e1b14a 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Poista turvasäilytyksestä"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Sovellus ei ehkä toimi jaetulla näytöllä."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Sovellus ei tue jaetun näytön tilaa."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string> <string name="accessibility_divider" msgid="703810061635792791">"Näytön jakaja"</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 5146d1c95cea..587c2950d358 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Retirer de la réserve"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"L\'application n\'est pas compatible avec l\'écran partagé."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 1ee8f680e9e2..0ede879cb7f7 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Application incompatible avec l\'écran partagé."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 6a8add897f45..1c692140e57a 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Non esconder"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Pode que a aplicación non funcione coa pantalla dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"A aplicación non é compatible coa función de pantalla dividida."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É posible que a aplicación non funcione nunha pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A aplicación non se pode iniciar en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index de1319955753..c50445c13778 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"બતાવો"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"વિભાજિત-સ્ક્રીન સાથે ઍપ કદાચ કામ ન કરે."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ઍપ્લિકેશન સ્ક્રીન-વિભાજનનું સમર્થન કરતી નથી."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર લૉન્ચનું સમર્થન કરતી નથી."</string> <string name="accessibility_divider" msgid="703810061635792791">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index df0ebb3a34a6..1a7cf3ea676a 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"दिखाएं"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ऐप्लिकेशन शायद स्प्लिट स्क्रीन मोड में काम न करे."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ऐप विभाजित स्क्रीन का समर्थन नहीं करता है."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string> <string name="accessibility_divider" msgid="703810061635792791">"विभाजित स्क्रीन विभाजक"</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 8d20c9d18f76..bf54411efdde 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Poništite sakrivanje"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće funkcionirati s podijeljenim zaslonom."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava podijeljeni zaslon."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog zaslona"</string> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index ed4c35449d1d..01f533f61a7f 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Félretevés megszüntetése"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Az alkalmazás nem támogatja az osztott képernyős nézetet."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string> <string name="accessibility_divider" msgid="703810061635792791">"Elválasztó az osztott nézetben"</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index 31ead019b867..f8ead655cc05 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ցուցադրել"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում։"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Հավելվածը չի աջակցում էկրանի տրոհումը:"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string> <string name="accessibility_divider" msgid="703810061635792791">"Տրոհված էկրանի բաժանիչ"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index e0e18019f3b0..dce6b38f8e5c 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Batalkan stash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikasi mungkin tidak berfungsi dengan layar terpisah."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App tidak mendukung layar terpisah."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pembagi layar terpisah"</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 4b0e812cb25e..f4c2221b094f 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Taka úr geymslu"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Hugsanlega virkar forritið ekki með skjáskiptingu."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Forritið styður ekki að skjánum sé skipt."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Forrit styður ekki opnun á öðrum skjá."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skjáskipting"</string> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 4226a845e6da..af5a0fb306d9 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Annulla accantonamento"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"L\'app potrebbe non funzionare con lo schermo diviso."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"L\'app non supporta la modalità Schermo diviso."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"L\'app potrebbe non funzionare su un display secondario."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'app non supporta l\'avvio su display secondari."</string> <string name="accessibility_divider" msgid="703810061635792791">"Strumento per schermo diviso"</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 038a2232ec66..7a07e6c8e34c 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ביטול ההסתרה הזמנית"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ייתכן שהאפליקציה לא תפעל במסך מפוצל."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"האפליקציה אינה תומכת במסך מפוצל."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ייתכן שהאפליקציה לא תפעל במסך משני."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"האפליקציה אינה תומכת בהפעלה במסכים משניים."</string> <string name="accessibility_divider" msgid="703810061635792791">"מחלק מסך מפוצל"</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 315f0740a94d..f3da0954dc07 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"表示"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"アプリは分割画面では動作しないことがあります。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"アプリで分割画面がサポートされていません。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分割画面の分割線"</string> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 1ff6ff84d0b4..36d4be07d82f 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"გადანახვის გაუქმება"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string> <string name="accessibility_divider" msgid="703810061635792791">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 933d0ca4400d..e7bcc996cfdf 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Көрсету"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Қолданба экранды бөлу режимінде жұмыс істемеуі мүмкін."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Қодланба бөлінген экранды қолдамайды."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Қолданба қосымша дисплейде жұмыс істемеуі мүмкін."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Қолданба қосымша дисплейлерде іске қосуды қолдамайды."</string> <string name="accessibility_divider" msgid="703810061635792791">"Бөлінген экран бөлгіші"</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index c1cb1dde28e8..04142d7ec5c2 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ឈប់លាក់ជាបណ្ដោះអាសន្ន"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"កម្មវិធីអាចនឹងមិនដំណើរការជាមួយមុខងារបំបែកអេក្រង់ទេ។"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"កម្មវិធីមិនគាំទ្រអេក្រង់បំបែកជាពីរទេ"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"កម្មវិធីនេះប្រហែលជាមិនដំណើរការនៅលើអេក្រង់បន្ទាប់បន្សំទេ។"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"កម្មវិធីនេះមិនអាចចាប់ផ្តើមនៅលើអេក្រង់បន្ទាប់បន្សំបានទេ។"</string> <string name="accessibility_divider" msgid="703810061635792791">"កម្មវិធីចែកអេក្រង់បំបែក"</string> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index c7fe59bcc983..e2c86a9e7be6 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ಅನ್ಸ್ಟ್ಯಾಶ್ ಮಾಡಿ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ವಿಭಜಿಸಿದ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ಆ್ಯಪ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> <string name="accessibility_divider" msgid="703810061635792791">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 17c51d9499c9..baa245aaa180 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"숨기기 취소"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"앱이 분할 화면에서 작동하지 않을 수 있습니다."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"앱이 화면 분할을 지원하지 않습니다."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"앱이 보조 디스플레이에서 작동하지 않을 수도 있습니다."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"앱이 보조 디스플레이에서의 실행을 지원하지 않습니다."</string> <string name="accessibility_divider" msgid="703810061635792791">"화면 분할기"</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 43292766e222..fdf33911e8f6 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Сейфтен чыгаруу"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Колдонмодо экран бөлүнбөшү мүмкүн."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Колдонмодо экран бөлүнбөйт."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string> <string name="accessibility_divider" msgid="703810061635792791">"Экранды бөлгүч"</string> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index e0a92b8a6fec..30631f963cd3 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ເອົາອອກຈາກບ່ອນເກັບສ່ວນຕົວ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບການແບ່ງໜ້າຈໍ."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ແອັບບໍ່ຮອງຮັບໜ້າຈໍແບບແຍກກັນ."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string> <string name="accessibility_divider" msgid="703810061635792791">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index 50565a74e5a0..bac36816893d 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Nebeslėpti"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Programa gali neveikti naudojant išskaidyto ekrano režimą."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Programoje nepalaikomas skaidytas ekranas."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Programa gali neveikti antriniame ekrane."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programa nepalaiko paleisties antriniuose ekranuose."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skaidyto ekrano daliklis"</string> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index 71260943f908..c74d4f949485 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Rādīt"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Iespējams, lietotne nedarbosies ekrāna sadalīšanas režīmā."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Lietotnē netiek atbalstīta ekrāna sadalīšana."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekrāna sadalītājs"</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 41f549e7b5c9..d64097fb19e1 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Прикажете"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Апликацијата може да не работи со поделен екран."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Апликацијата не поддржува поделен екран."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликацијата може да не функционира на друг екран."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликацијата не поддржува стартување на други екрани."</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделник на поделен екран"</string> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index b21e5b4daa9c..1f2ee77079bc 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"അൺസ്റ്റാഷ് ചെയ്യൽ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"സ്ക്രീൻ വിഭജന മോഡിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"രണ്ടാം ഡിസ്പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"രണ്ടാം ഡിസ്പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string> <string name="accessibility_divider" msgid="703810061635792791">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index d71325881f69..b9cf9458722a 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ил гаргах"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Апп хуваагдсан дэлгэц дээр ажиллахгүй байж болзошгүй."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Энэ апп нь дэлгэц хуваах тохиргоог дэмждэггүй."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апп хоёрдогч дэлгэцэд ажиллахгүй."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Аппыг хоёрдогч дэлгэцэд эхлүүлэх боломжгүй."</string> <string name="accessibility_divider" msgid="703810061635792791">"\"Дэлгэц хуваах\" хуваагч"</string> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index 1b53175dd9f5..19de9764a2f5 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"अनस्टॅश करा"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"अॅप कदाचित स्प्लिट स्क्रीनसह काम करू शकत नाही."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"दुसऱ्या डिस्प्लेवर अॅप कदाचित चालणार नाही."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"दुसऱ्या डिस्प्लेवर अॅप लाँच होणार नाही."</string> <string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रीन विभाजक"</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index e648a7a70d10..4581a7740238 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Tunjukkan"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Apl mungkin tidak berfungsi dengan skrin pisah."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Apl tidak menyokong skrin pisah."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Apl mungkin tidak berfungsi pada paparan kedua."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Apl tidak menyokong pelancaran pada paparan kedua."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pembahagi skrin pisah"</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 96a64122dba4..6f8fed97c1aa 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"မသိုဝှက်ရန်"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းဖြင့် အက်ပ်သည် အလုပ်မလုပ်ပါ။"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"အက်ပ်သည် မျက်နှာပြင်ခွဲပြရန် ပံ့ပိုးထားခြင်းမရှိပါ။"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string> <string name="accessibility_divider" msgid="703810061635792791">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index b6cea3fea606..e0108e3dec2b 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Avslutt oppbevaring"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Det kan hende at appen ikke fungerer med delt skjerm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Appen støtter ikke delt skjerm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer kanskje ikke på en sekundær skjerm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke kjøres på sekundære skjermer."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skilleelement for delt skjerm"</string> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 4413a43b212e..0f6b155dc0b9 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"अनस्ट्यास गर्नुहोस्"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"एप विभाजित स्क्रिनमा काम नगर्न सक्छ।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो एपले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string> <string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रिन छुट्याउने"</string> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index 2e451438bf3b..f6a69757055f 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Niet meer verbergen"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"De app werkt mogelijk niet met gesplitst scherm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"App biedt geen ondersteuning voor gesplitst scherm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App werkt mogelijk niet op een secundair scherm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App kan niet op secundaire displays worden gestart."</string> <string name="accessibility_divider" msgid="703810061635792791">"Scheiding voor gesplitst scherm"</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index 7f0897ff9f24..e3e8b84a2e46 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ଦେଖାନ୍ତୁ"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରିନରେ ଆପ୍ କାମ କରିନପାରେ।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ଆପ୍ ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନକୁ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ କାମ ନକରିପାରେ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> <string name="accessibility_divider" msgid="703810061635792791">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index aa250d5b7f93..16310ffe0f6c 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ਅਣਸਟੈਸ਼"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string> <string name="accessibility_divider" msgid="703810061635792791">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 3c3d7aa636b7..fd6434af15df 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zabierz ze schowka"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacja może nie działać przy podzielonym ekranie."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacja nie obsługuje dzielonego ekranu."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacja może nie działać na dodatkowym ekranie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string> <string name="accessibility_divider" msgid="703810061635792791">"Linia dzielenia ekranu"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index cad59e0d40f0..8cf331419b86 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Exibir"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"É possível que o app não funcione com a tela dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"O app não é compatível com a divisão de tela."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 26772dcdda00..d4d5ae62499e 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Remover do armazenamento"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"A app pode não funcionar com o ecrã dividido."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"A app não é compatível com o ecrã dividido."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"A app pode não funcionar num ecrã secundário."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A app não é compatível com o início em ecrãs secundários."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor do ecrã dividido"</string> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index cad59e0d40f0..8cf331419b86 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Exibir"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"É possível que o app não funcione com a tela dividida."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"O app não é compatível com a divisão de tela."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 607d99754393..44220da9494c 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Anulează stocarea"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplicația nu acceptă ecranul împărțit."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplicația nu acceptă lansare pe ecrane secundare."</string> <string name="accessibility_divider" msgid="703810061635792791">"Separator pentru ecranul împărțit"</string> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index bed76e493589..88168954976b 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Показать"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"В режиме разделения экрана приложение может работать нестабильно."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Приложение не поддерживает разделение экрана."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Приложение может не работать на дополнительном экране"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложение не поддерживает запуск на дополнительных экранах"</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделитель экрана"</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 0ed3b8edb53b..37c1205941dd 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"සඟවා තැබීම ඉවත් කරන්න"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"යෙදුම බෙදුම් තිරය සමග ක්රියා නොකළ හැකිය"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"යෙදුම බෙදුණු-තිරය සඳහා සහාය නොදක්වයි."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"යෙදුම ද්විතියික සංදර්ශකයක ක්රියා නොකළ හැකිය."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"යෙදුම ද්විතීයික සංදර්ශක මත දියත් කිරීම සඳහා සහාය නොදක්වයි."</string> <string name="accessibility_divider" msgid="703810061635792791">"බෙදුම්-තිර වෙන්කරණය"</string> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index f20e940c50f3..d6900d00d453 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zrušiť skrytie"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikácia nemusí fungovať s rozdelenou obrazovkou."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikácia nepodporuje rozdelenú obrazovku."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string> <string name="accessibility_divider" msgid="703810061635792791">"Rozdeľovač obrazovky"</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index e2063d85673b..b0a8587dca5a 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Razkrij"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija morda ne deluje v načinu razdeljenega zaslona."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podpira načina razdeljenega zaslona."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdelilnik zaslonov"</string> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index 0c3947d52f34..f4a22d427b77 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Mos e fshih"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacioni mund të mos funksionojë me ekranin e ndarë."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacioni nuk mbështet ekranin e ndarë."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ndarësi i ekranit të ndarë"</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 140d3dba8d84..3d96c655c22e 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Уклоните из тајне меморије"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Апликација можда неће радити са подељеним екраном."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Апликација не подржава подељени екран."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликација можда неће функционисати на секундарном екрану."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликација не подржава покретање на секундарним екранима."</string> <string name="accessibility_divider" msgid="703810061635792791">"Разделник подељеног екрана"</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 62220c48458c..b7d2584b2564 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Återställ stash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Appen kanske inte fungerar med delad skärm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Appen har inte stöd för delad skärm."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen kanske inte fungerar på en sekundär skärm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan inte köras på en sekundär skärm."</string> <string name="accessibility_divider" msgid="703810061635792791">"Avdelare för delad skärm"</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 232b268fff03..fa46229c8894 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Fichua"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Huenda programu isifanye kazi kwenye skrini inayogawanywa."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Programu haiwezi kutumia skrini iliyogawanywa."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Huenda programu isifanye kazi kwenye dirisha lingine."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string> <string name="accessibility_divider" msgid="703810061635792791">"Kitenganishi cha skrini inayogawanywa"</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 90bf26373049..2039685ecc53 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"திரைப் பிரிப்பு அம்சத்தில் ஆப்ஸ் செயல்படாமல் போகக்கூடும்."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"திரையைப் பிரிப்பதைப் ஆப்ஸ் ஆதரிக்கவில்லை."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"இரண்டாம்நிலைத் திரையில் ஆப்ஸ் வேலை செய்யாமல் போகக்கூடும்."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string> <string name="accessibility_divider" msgid="703810061635792791">"திரையைப் பிரிக்கும் பிரிப்பான்"</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 7a2a8a88c51e..f0daac946fcf 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ఆన్స్టాచ్"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"స్క్రీన్ విభజనతో యాప్ పని చేయకపోవచ్చు."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"యాప్లో స్క్రీన్ విభజనకు మద్దతు లేదు."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ప్రత్యామ్నాయ డిస్ప్లేలో యాప్ పని చేయకపోవచ్చు."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ప్రత్యామ్నాయ డిస్ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string> <string name="accessibility_divider" msgid="703810061635792791">"విభజన స్క్రీన్ విభాగిని"</string> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index 76cbb1ab307e..74a55c346059 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"เอาออกจากที่เก็บส่วนตัว"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"แอปอาจใช้ไม่ได้กับโหมดแบ่งหน้าจอ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"แอปไม่สนับสนุนการแยกหน้าจอ"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"แอปอาจไม่ทำงานในจอแสดงผลรอง"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"แอปไม่รองรับการเรียกใช้ในจอแสดงผลรอง"</string> <string name="accessibility_divider" msgid="703810061635792791">"เส้นแบ่งหน้าจอ"</string> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index 103d072fac52..58ef31bf918c 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"I-unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Posibleng hindi gumana ang app sa split screen."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Hindi sinusuportahan ng app ang split-screen."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Maaaring hindi gumana ang app sa pangalawang display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divider ng split-screen"</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 0b82db77589e..6ca95986658e 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Depolama"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Uygulama bölünmüş ekranda çalışmayabilir."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Uygulama bölünmüş ekranı desteklemiyor."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uygulama ikincil ekranda çalışmayabilir."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcı"</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 59b767341099..084fdb28c6b0 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Показати"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Додаток може не працювати в режимі розділеного екрана."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Додаток не підтримує розділення екрана."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Додаток може не працювати на додатковому екрані."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Додаток не підтримує запуск на додаткових екранах."</string> <string name="accessibility_divider" msgid="703810061635792791">"Розділювач екрана"</string> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 743c06353808..645be3731bb1 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"ممکن ہے کہ ایپ اسپلٹ اسکرین کے ساتھ کام نہ کرے۔"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string> <string name="accessibility_divider" msgid="703810061635792791">"سپلٹ اسکرین تقسیم کار"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 3b9324fc3b4d..923e7b2d6bb6 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Chiqarish"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Bu ilova ekranni ikkiga ajratish rejimini dastaklamaydi."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Bu ilova ekranni bo‘lish xususiyatini qo‘llab-quvvatlamaydi."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekranni ikkiga bo‘lish chizig‘i"</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 8583621e5519..b151d72eef30 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Hiện"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Ứng dụng có thể không hoạt động với tính năng chia đôi màn hình."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Ứng dụng không hỗ trợ chia đôi màn hình."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bộ chia chia đôi màn hình"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index d20626da8803..66b5a4be2967 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消隐藏"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"应用可能无法在分屏模式下正常运行。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"应用不支持分屏。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"应用可能无法在辅显示屏上正常运行。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"应用不支持在辅显示屏上启动。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分屏分隔线"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index f53dc7d763e2..1a2e37701298 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消保護"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"應用程式可能無法在分割畫面中運作。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"應用程式不支援分割畫面。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示屏上運作。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示屏上啟動。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 4b33ab653b5e..99a79cfa228f 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消暫時隱藏"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"應用程式可能無法在分割畫面中運作。"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"這個應用程式不支援分割畫面。"</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示器上運作。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示器上啟動。"</string> <string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index cd128b644a25..cfafb61b1562 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -34,6 +34,8 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Susa isiteshi"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Izinhlelo zokusebenza kungenzeka zingasebenzi ngesikrini esihlukanisiwe."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe."</string> + <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) --> + <skip /> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string> <string name="accessibility_divider" msgid="703810061635792791">"Isihlukanisi sokuhlukanisa isikrini"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java index 65a7d09dafa3..d10a6744b5f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java @@ -86,11 +86,11 @@ class ActivityEmbeddingAnimationSpec { final int startLeft; final int startTop; if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { - // The window will be animated in from left or right depends on its position. + // The window will be animated in from left or right depending on its position. startTop = 0; startLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); } else { - // The window will be animated in from top or bottom depends on its position. + // The window will be animated in from top or bottom depending on its position. startTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); startLeft = 0; } @@ -114,11 +114,11 @@ class ActivityEmbeddingAnimationSpec { final int endTop; final int endLeft; if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { - // The window will be animated out to left or right depends on its position. + // The window will be animated out to left or right depending on its position. endTop = 0; endLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); } else { - // The window will be animated out to top or bottom depends on its position. + // The window will be animated out to top or bottom depending on its position. endTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); endLeft = 0; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java index e3382211da79..6af81f1eb707 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java @@ -322,6 +322,7 @@ public class TransitionAnimationHelper { .setPixelFormat(PixelFormat.RGBA_8888) .setChildrenOnly(true) .setAllowProtected(true) + .setCaptureSecureLayers(true) .build(); final ScreenCapture.ScreenshotHardwareBuffer edgeBuffer = ScreenCapture.captureLayers(captureArgs); diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index c740832522fc..b2b95b72e0e0 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -1830,6 +1830,28 @@ inline ResTable_overlayable_policy_header::PolicyFlags& operator |=( return first; } +using ResourceId = uint32_t; // 0xpptteeee + +using DataType = uint8_t; // Res_value::dataType +using DataValue = uint32_t; // Res_value::data + +struct OverlayManifestInfo { + std::string package_name; // NOLINT(misc-non-private-member-variables-in-classes) + std::string name; // NOLINT(misc-non-private-member-variables-in-classes) + std::string target_package; // NOLINT(misc-non-private-member-variables-in-classes) + std::string target_name; // NOLINT(misc-non-private-member-variables-in-classes) + ResourceId resource_mapping; // NOLINT(misc-non-private-member-variables-in-classes) +}; + +struct FabricatedOverlayEntryParameters { + std::string resource_name; + DataType data_type; + DataValue data_value; + std::string data_string_value; + std::optional<android::base::borrowed_fd> data_binary_value; + std::string configuration; +}; + class AssetManager2; /** diff --git a/libs/hwui/jni/MeshSpecification.cpp b/libs/hwui/jni/MeshSpecification.cpp new file mode 100644 index 000000000000..22fa4d39e2ed --- /dev/null +++ b/libs/hwui/jni/MeshSpecification.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <SkMesh.h> + +#include "GraphicsJNI.h" +#include "graphics_jni_helpers.h" + +namespace android { + +using Attribute = SkMeshSpecification::Attribute; +using Varying = SkMeshSpecification::Varying; + +static struct { + jclass clazz{}; + jfieldID type{}; + jfieldID offset{}; + jfieldID name{}; +} gAttributeInfo; + +static struct { + jclass clazz{}; + jfieldID type{}; + jfieldID name{}; +} gVaryingInfo; + +std::vector<Attribute> extractAttributes(JNIEnv* env, jobjectArray attributes) { + int size = env->GetArrayLength(attributes); + std::vector<Attribute> attVector; + attVector.reserve(size); + for (int i = 0; i < size; i++) { + jobject attribute = env->GetObjectArrayElement(attributes, i); + auto name = (jstring)env->GetObjectField(attribute, gAttributeInfo.name); + auto attName = ScopedUtfChars(env, name); + Attribute temp{Attribute::Type(env->GetIntField(attribute, gAttributeInfo.type)), + static_cast<size_t>(env->GetIntField(attribute, gAttributeInfo.offset)), + SkString(attName.c_str())}; + attVector.push_back(std::move(temp)); + } + + return attVector; +} + +std::vector<Varying> extractVaryings(JNIEnv* env, jobjectArray varyings) { + int size = env->GetArrayLength(varyings); + std::vector<Varying> varyVector; + varyVector.reserve(size); + for (int i = 0; i < size; i++) { + jobject varying = env->GetObjectArrayElement(varyings, i); + auto name = (jstring)env->GetObjectField(varying, gVaryingInfo.name); + auto varyName = ScopedUtfChars(env, name); + Varying temp{Varying::Type(env->GetIntField(varying, gVaryingInfo.type)), + SkString(varyName.c_str())}; + varyVector.push_back(std::move(temp)); + } + + return varyVector; +} + +static jlong Make(JNIEnv* env, jobject thiz, jobjectArray attributeArray, jint vertexStride, + jobjectArray varyingArray, jstring vertexShader, jstring fragmentShader) { + auto attributes = extractAttributes(env, attributeArray); + auto varyings = extractVaryings(env, varyingArray); + auto skVertexShader = ScopedUtfChars(env, vertexShader); + auto skFragmentShader = ScopedUtfChars(env, fragmentShader); + auto meshSpec = SkMeshSpecification::Make(attributes, vertexStride, varyings, + SkString(skVertexShader.c_str()), + SkString(skFragmentShader.c_str())) + .specification; + return reinterpret_cast<jlong>(meshSpec.release()); +} + +static jlong MakeWithCS(JNIEnv* env, jobject thiz, jobjectArray attributeArray, jint vertexStride, + jobjectArray varyingArray, jstring vertexShader, jstring fragmentShader, + jlong colorSpace) { + auto attributes = extractAttributes(env, attributeArray); + auto varyings = extractVaryings(env, varyingArray); + auto skVertexShader = ScopedUtfChars(env, vertexShader); + auto skFragmentShader = ScopedUtfChars(env, fragmentShader); + auto meshSpec = SkMeshSpecification::Make(attributes, vertexStride, varyings, + SkString(skVertexShader.c_str()), + SkString(skFragmentShader.c_str()), + GraphicsJNI::getNativeColorSpace(colorSpace)) + .specification; + + return reinterpret_cast<jlong>(meshSpec.release()); +} + +static jlong MakeWithAlpha(JNIEnv* env, jobject thiz, jobjectArray attributeArray, + jint vertexStride, jobjectArray varyingArray, jstring vertexShader, + jstring fragmentShader, jlong colorSpace, jint alphaType) { + auto attributes = extractAttributes(env, attributeArray); + auto varyings = extractVaryings(env, varyingArray); + auto skVertexShader = ScopedUtfChars(env, vertexShader); + auto skFragmentShader = ScopedUtfChars(env, fragmentShader); + auto meshSpec = SkMeshSpecification::Make( + attributes, vertexStride, varyings, SkString(skVertexShader.c_str()), + SkString(skFragmentShader.c_str()), + GraphicsJNI::getNativeColorSpace(colorSpace), SkAlphaType(alphaType)) + .specification; + return reinterpret_cast<jlong>(meshSpec.release()); +} + +static void MeshSpecification_safeUnref(SkMeshSpecification* meshSpec) { + SkSafeUnref(meshSpec); +} + +static jlong getMeshSpecificationFinalizer() { + return static_cast<jlong>(reinterpret_cast<uintptr_t>(&MeshSpecification_safeUnref)); +} + +static const JNINativeMethod gMeshSpecificationMethods[] = { + {"nativeGetFinalizer", "()J", (void*)getMeshSpecificationFinalizer}, + {"nativeMake", + "([Landroid/graphics/MeshSpecification$Attribute;I[Landroid/graphics/" + "MeshSpecification$Varying;" + "Ljava/lang/String;Ljava/lang/String;)J", + (void*)Make}, + {"nativeMakeWithCS", + "([Landroid/graphics/MeshSpecification$Attribute;I" + "[Landroid/graphics/MeshSpecification$Varying;Ljava/lang/String;Ljava/lang/String;J)J", + (void*)MakeWithCS}, + {"nativeMakeWithAlpha", + "([Landroid/graphics/MeshSpecification$Attribute;I" + "[Landroid/graphics/MeshSpecification$Varying;Ljava/lang/String;Ljava/lang/String;JI)J", + (void*)MakeWithAlpha}}; + +int register_android_graphics_MeshSpecification(JNIEnv* env) { + android::RegisterMethodsOrDie(env, "android/graphics/MeshSpecification", + gMeshSpecificationMethods, NELEM(gMeshSpecificationMethods)); + + gAttributeInfo.clazz = env->FindClass("android/graphics/MeshSpecification$Attribute"); + gAttributeInfo.type = env->GetFieldID(gAttributeInfo.clazz, "mType", "I"); + gAttributeInfo.offset = env->GetFieldID(gAttributeInfo.clazz, "mOffset", "I"); + gAttributeInfo.name = env->GetFieldID(gAttributeInfo.clazz, "mName", "Ljava/lang/String;"); + + gVaryingInfo.clazz = env->FindClass("android/graphics/MeshSpecification$Varying"); + gVaryingInfo.type = env->GetFieldID(gVaryingInfo.clazz, "mType", "I"); + gVaryingInfo.name = env->GetFieldID(gVaryingInfo.clazz, "mName", "Ljava/lang/String;"); + return 0; +} + +} // namespace android
\ No newline at end of file diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java index 40f6dc541f86..4e2ce91342fc 100644 --- a/media/java/android/media/AudioDeviceVolumeManager.java +++ b/media/java/android/media/AudioDeviceVolumeManager.java @@ -21,7 +21,6 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.content.Context; import android.os.IBinder; @@ -44,8 +43,7 @@ import java.util.concurrent.Executor; @SystemApi public class AudioDeviceVolumeManager { - // define when using Log.* - //private static final String TAG = "AudioDeviceVolumeManager"; + private static final String TAG = "AudioDeviceVolumeManager"; /** @hide * Indicates no special treatment in the handling of the volume adjustment */ @@ -70,20 +68,15 @@ public class AudioDeviceVolumeManager { private static IAudioService sService; private final @NonNull String mPackageName; - private final @Nullable String mAttributionTag; /** + * @hide * Constructor * @param context the Context for the device volume operations */ - @SuppressLint("ManagerConstructor") - // reason for suppression: even though the functionality handled by this class is implemented in - // AudioService, we want to avoid bloating android.media.AudioManager - // with @SystemApi functionality public AudioDeviceVolumeManager(@NonNull Context context) { Objects.requireNonNull(context); mPackageName = context.getApplicationContext().getOpPackageName(); - mAttributionTag = context.getApplicationContext().getAttributionTag(); } /** @@ -325,13 +318,38 @@ public class AudioDeviceVolumeManager { * @param ada the device for which volume is to be modified */ @SystemApi + // TODO alternatively require MODIFY_AUDIO_SYSTEM_SETTINGS when defined @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada) { try { - getService().setDeviceVolume(vi, ada, mPackageName, mAttributionTag); + getService().setDeviceVolume(vi, ada, mPackageName); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * @hide + * Returns the volume on the given audio device for the given volume information. + * For instance if using a {@link VolumeInfo} configured for {@link AudioManager#STREAM_ALARM}, + * it will return the alarm volume. When no volume index has ever been set for the given + * device, the default volume will be returned (the volume setting that would have been + * applied if playback for that use case had started). + * @param vi the volume information, only stream-based volumes are supported. Information + * other than the stream type is ignored. + * @param ada the device for which volume is to be retrieved + */ + @SystemApi + // TODO alternatively require MODIFY_AUDIO_SYSTEM_SETTINGS when defined + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi, + @NonNull AudioDeviceAttributes ada) { + try { + return getService().getDeviceVolume(vi, ada, mPackageName); } catch (RemoteException e) { e.rethrowFromSystemServer(); } + return VolumeInfo.getDefaultVolumeInfo(); } /** diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 17d7045eacaf..f3931df03327 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1212,7 +1212,13 @@ public class AudioManager { } } - private static boolean isPublicStreamType(int streamType) { + /** + * @hide + * Checks whether a stream type is part of the public SDK + * @param streamType + * @return true if the stream type is available in SDK + */ + public static boolean isPublicStreamType(int streamType) { switch (streamType) { case STREAM_VOICE_CALL: case STREAM_SYSTEM: diff --git a/media/java/android/media/AudioTimestamp.aidl b/media/java/android/media/AudioTimestamp.aidl new file mode 100644 index 000000000000..2c161b319de1 --- /dev/null +++ b/media/java/android/media/AudioTimestamp.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +parcelable AudioTimestamp; diff --git a/media/java/android/media/AudioTimestamp.java b/media/java/android/media/AudioTimestamp.java index be8ca151580d..a3277e53ea70 100644 --- a/media/java/android/media/AudioTimestamp.java +++ b/media/java/android/media/AudioTimestamp.java @@ -16,11 +16,14 @@ package android.media; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import android.annotation.IntDef; - /** * Structure that groups a position in frame units relative to an assumed audio stream, * together with the estimated time when that frame enters or leaves the audio @@ -33,8 +36,7 @@ import android.annotation.IntDef; * @see AudioTrack#getTimestamp AudioTrack.getTimestamp(AudioTimestamp) * @see AudioRecord#getTimestamp AudioRecord.getTimestamp(AudioTimestamp, int) */ -public final class AudioTimestamp -{ +public final class AudioTimestamp implements Parcelable { /** * Clock monotonic or its equivalent on the system, * in the same units and timebase as {@link java.lang.System#nanoTime}. @@ -86,4 +88,47 @@ public final class AudioTimestamp * with a timebase of {@link #TIMEBASE_MONOTONIC}. */ public long nanoTime; + + public AudioTimestamp() { + } + + private AudioTimestamp(@NonNull Parcel in) { + framePosition = in.readLong(); + nanoTime = in.readLong(); + } + + @Override + public String toString() { + return "AudioTimeStamp:" + + " framePos=" + framePosition + + " nanoTime=" + nanoTime; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeLong(framePosition); + dest.writeLong(nanoTime); + } + + @Override + public int describeContents() { + return 0; + } + + /** + * Creates an instance from a {@link Parcel}. + */ + @NonNull + public static final Creator<AudioTimestamp> CREATOR = new Creator<>() { + @Override + public AudioTimestamp createFromParcel(@NonNull Parcel in) { + return new AudioTimestamp(in); + } + + @Override + public AudioTimestamp[] newArray(int size) { + return new AudioTimestamp[size]; + } + }; } + diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 7c9e49442564..2e766d59fbb3 100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -102,7 +102,10 @@ interface IAudioService { in String callingPackage, in String attributionTag); void setDeviceVolume(in VolumeInfo vi, in AudioDeviceAttributes ada, - in String callingPackage, in String attributionTag); + in String callingPackage); + + VolumeInfo getDeviceVolume(in VolumeInfo vi, in AudioDeviceAttributes ada, + in String callingPackage); oneway void handleVolumeKey(in KeyEvent event, boolean isOnTv, String callingPackage, String caller); diff --git a/media/java/android/media/IMediaRouter2Manager.aidl b/media/java/android/media/IMediaRouter2Manager.aidl index 9f3c3ff89032..bb31859dabdb 100644 --- a/media/java/android/media/IMediaRouter2Manager.aidl +++ b/media/java/android/media/IMediaRouter2Manager.aidl @@ -19,6 +19,7 @@ package android.media; import android.media.MediaRoute2ProviderInfo; import android.media.MediaRoute2Info; import android.media.RouteDiscoveryPreference; +import android.media.RouteListingPreference; import android.media.RoutingSessionInfo; /** @@ -30,6 +31,8 @@ oneway interface IMediaRouter2Manager { void notifySessionReleased(in RoutingSessionInfo session); void notifyDiscoveryPreferenceChanged(String packageName, in RouteDiscoveryPreference discoveryPreference); + void notifyRouteListingPreferenceChange(String packageName, + in @nullable RouteListingPreference routeListingPreference); void notifyRoutesUpdated(in List<MediaRoute2Info> routes); void notifyRequestFailed(int requestId, int reason); } diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl index 742207b2d9e8..bddda4ab5002 100644 --- a/media/java/android/media/IMediaRouterService.aidl +++ b/media/java/android/media/IMediaRouterService.aidl @@ -23,6 +23,7 @@ import android.media.IMediaRouterClient; import android.media.MediaRoute2Info; import android.media.MediaRouterClientState; import android.media.RouteDiscoveryPreference; +import android.media.RouteListingPreference; import android.media.RoutingSessionInfo; import android.os.Bundle; @@ -57,6 +58,8 @@ interface IMediaRouterService { void unregisterRouter2(IMediaRouter2 router); void setDiscoveryRequestWithRouter2(IMediaRouter2 router, in RouteDiscoveryPreference preference); + void setRouteListingPreference(IMediaRouter2 router, + in @nullable RouteListingPreference routeListingPreference); void setRouteVolumeWithRouter2(IMediaRouter2 router, in MediaRoute2Info route, int volume); void requestCreateSessionWithRouter2(IMediaRouter2 router, int requestId, long managerRequestId, diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java index 681e1124d0ab..e8648cca3934 100644 --- a/media/java/android/media/MediaRoute2Info.java +++ b/media/java/android/media/MediaRoute2Info.java @@ -28,6 +28,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import com.android.internal.util.Preconditions; + import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -374,6 +376,7 @@ public final class MediaRoute2Info implements Parcelable { MediaRoute2Info(@NonNull Parcel in) { mId = in.readString(); + Preconditions.checkArgument(!TextUtils.isEmpty(mId)); mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mFeatures = in.createStringArrayList(); mType = in.readInt(); @@ -403,7 +406,7 @@ public final class MediaRoute2Info implements Parcelable { */ @NonNull public String getId() { - if (mProviderId != null) { + if (!TextUtils.isEmpty(mProviderId)) { return toUniqueId(mProviderId, mId); } else { return mId; diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index a28ea32bf3ce..d57a56a09fdb 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -112,6 +112,10 @@ public final class MediaRouter2 { @GuardedBy("mLock") final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>(); + @GuardedBy("mLock") + @Nullable + private RouteListingPreference mRouteListingPreference; + final RoutingController mSystemController; @GuardedBy("mLock") @@ -461,6 +465,52 @@ public final class MediaRouter2 { } } + /** + * Sets the {@link RouteListingPreference} of the app associated to this media router. + * + * <p>Use this method to inform the system UI of the routes that you would like to list for + * media routing, via the Output Switcher. + * + * <p>You should call this method before {@link #registerRouteCallback registering any route + * callbacks} and immediately after receiving any {@link RouteCallback#onRoutesUpdated route + * updates} in order to keep the system UI in a consistent state. You can also call this method + * at any other point to update the listing preference dynamically. + * + * <p>Notes: + * + * <ol> + * <li>You should not include the ids of two or more routes with a match in their {@link + * MediaRoute2Info#getDeduplicationIds() deduplication ids}. If you do, the system will + * deduplicate them using its own criteria. + * <li>You can use this method to rank routes in the output switcher, placing the more + * important routes first. The system might override the proposed ranking. + * <li>You can use this method to avoid listing routes using dynamic criteria. For example, + * you can limit access to a specific type of device according to runtime criteria. + * </ol> + * + * @param routeListingPreference The {@link RouteListingPreference} for the system to use for + * route listing. When null, the system uses its default listing criteria. + */ + public void setRouteListingPreference(@Nullable RouteListingPreference routeListingPreference) { + synchronized (mLock) { + if (Objects.equals(mRouteListingPreference, routeListingPreference)) { + // Nothing changed. We return early to save a call to the system server. + return; + } + mRouteListingPreference = routeListingPreference; + try { + if (mStub == null) { + MediaRouter2Stub stub = new MediaRouter2Stub(); + mMediaRouterService.registerRouter2(stub, mPackageName); + mStub = stub; + } + mMediaRouterService.setRouteListingPreference(mStub, mRouteListingPreference); + } catch (RemoteException ex) { + ex.rethrowFromSystemServer(); + } + } + } + @GuardedBy("mLock") private boolean updateDiscoveryPreferenceIfNeededLocked() { RouteDiscoveryPreference newDiscoveryPreference = new RouteDiscoveryPreference.Builder( diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java index e403e246f318..7786f619840a 100644 --- a/media/java/android/media/MediaRouter2Manager.java +++ b/media/java/android/media/MediaRouter2Manager.java @@ -35,6 +35,7 @@ import android.util.Log; 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; @@ -93,6 +94,11 @@ public final class MediaRouter2Manager { @NonNull final ConcurrentMap<String, RouteDiscoveryPreference> mDiscoveryPreferenceMap = new ConcurrentHashMap<>(); + // TODO(b/241888071): Merge mDiscoveryPreferenceMap and mPackageToRouteListingPreferenceMap into + // a single record object maintained by a single package-to-record map. + @NonNull + private final ConcurrentMap<String, RouteListingPreference> + mPackageToRouteListingPreferenceMap = new ConcurrentHashMap<>(); private final AtomicInteger mNextRequestId = new AtomicInteger(1); private final CopyOnWriteArrayList<TransferRequest> mTransferRequests = @@ -355,6 +361,16 @@ public final class MediaRouter2Manager { } /** + * Returns the {@link RouteListingPreference} of the app with the given {@code packageName}, or + * null if the app has not set any. + */ + @Nullable + public RouteListingPreference getRouteListingPreference(@NonNull String packageName) { + Preconditions.checkArgument(!TextUtils.isEmpty(packageName)); + return mPackageToRouteListingPreferenceMap.get(packageName); + } + + /** * Gets the system routing session for the given {@code packageName}. * Apps can select a route that is not the global route. (e.g. an app can select the device * route while BT route is available.) @@ -686,6 +702,24 @@ public final class MediaRouter2Manager { } } + private void updateRouteListingPreference( + @NonNull String packageName, @Nullable RouteListingPreference routeListingPreference) { + RouteListingPreference oldRouteListingPreference = + routeListingPreference == null + ? mPackageToRouteListingPreferenceMap.remove(packageName) + : mPackageToRouteListingPreferenceMap.put( + packageName, routeListingPreference); + if (Objects.equals(oldRouteListingPreference, routeListingPreference)) { + return; + } + for (CallbackRecord record : mCallbackRecords) { + record.mExecutor.execute( + () -> + record.mCallback.onRouteListingPreferenceUpdated( + packageName, routeListingPreference)); + } + } + /** * Gets the unmodifiable list of selected routes for the session. */ @@ -971,6 +1005,19 @@ public final class MediaRouter2Manager { } /** + * Called when the app with the given {@code packageName} updates its {@link + * MediaRouter2#setRouteListingPreference route listing preference}. + * + * @param packageName The package name of the app that changed its listing preference. + * @param routeListingPreference The new {@link RouteListingPreference} set by the app with + * the given {@code packageName}. Maybe null if an app has unset its preference (by + * passing null to {@link MediaRouter2#setRouteListingPreference}). + */ + default void onRouteListingPreferenceUpdated( + @NonNull String packageName, + @Nullable RouteListingPreference routeListingPreference) {} + + /** * Called when a previous request has failed. * * @param reason the reason that the request has failed. Can be one of followings: @@ -1056,6 +1103,17 @@ public final class MediaRouter2Manager { } @Override + public void notifyRouteListingPreferenceChange( + String packageName, @Nullable RouteListingPreference routeListingPreference) { + mHandler.sendMessage( + obtainMessage( + MediaRouter2Manager::updateRouteListingPreference, + MediaRouter2Manager.this, + packageName, + routeListingPreference)); + } + + @Override public void notifyRoutesUpdated(List<MediaRoute2Info> routes) { mHandler.sendMessage( obtainMessage( diff --git a/media/java/android/media/MediaRouter2Utils.java b/media/java/android/media/MediaRouter2Utils.java index c15972dcff2e..6f946ee23ed9 100644 --- a/media/java/android/media/MediaRouter2Utils.java +++ b/media/java/android/media/MediaRouter2Utils.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.text.TextUtils; import android.util.Log; +import com.android.internal.util.Preconditions; + /** * @hide */ @@ -31,14 +33,8 @@ public class MediaRouter2Utils { @NonNull public static String toUniqueId(@NonNull String providerId, @NonNull String id) { - if (TextUtils.isEmpty(providerId)) { - Log.w(TAG, "toUniqueId: providerId shouldn't be empty"); - return null; - } - if (TextUtils.isEmpty(id)) { - Log.w(TAG, "toUniqueId: id shouldn't be null"); - return null; - } + Preconditions.checkArgument(!TextUtils.isEmpty(providerId) + && !TextUtils.isEmpty(id)); return providerId + SEPARATOR + id; } diff --git a/media/java/android/media/RouteListingPreference.aidl b/media/java/android/media/RouteListingPreference.aidl new file mode 100644 index 000000000000..844dc8f7920d --- /dev/null +++ b/media/java/android/media/RouteListingPreference.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +parcelable RouteListingPreference; diff --git a/media/java/android/media/RouteListingPreference.java b/media/java/android/media/RouteListingPreference.java new file mode 100644 index 000000000000..26b190b9fd81 --- /dev/null +++ b/media/java/android/media/RouteListingPreference.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import com.android.internal.util.Preconditions; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Allows applications to customize the list of routes used for media routing (for example, in the + * System UI Output Switcher). + * + * @see MediaRouter2#setRouteListingPreference + */ +public final class RouteListingPreference implements Parcelable { + + @NonNull + public static final Creator<RouteListingPreference> CREATOR = + new Creator<>() { + @Override + public RouteListingPreference createFromParcel(Parcel in) { + return new RouteListingPreference(in); + } + + @Override + public RouteListingPreference[] newArray(int size) { + return new RouteListingPreference[size]; + } + }; + + @NonNull private final List<Item> mItems; + + /** + * Creates an instance with the given values. + * + * @param items See {@link #getItems()}. + */ + public RouteListingPreference(@NonNull List<Item> items) { + mItems = List.copyOf(Objects.requireNonNull(items)); + } + + private RouteListingPreference(Parcel in) { + List<Item> items = + in.readParcelableList(new ArrayList<>(), Item.class.getClassLoader(), Item.class); + mItems = List.copyOf(items); + } + + /** + * Returns an unmodifiable list containing the items that the app wants to be listed for media + * routing. + */ + @NonNull + public List<Item> getItems() { + return mItems; + } + + // RouteListingPreference Parcelable implementation. + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeParcelableList(mItems, flags); + } + + // Equals and hashCode. + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof RouteListingPreference)) { + return false; + } + RouteListingPreference that = (RouteListingPreference) other; + return mItems.equals(that.mItems); + } + + @Override + public int hashCode() { + return Objects.hash(mItems); + } + + // Internal classes. + + /** Holds preference information for a specific route in a media routing listing. */ + public static final class Item implements Parcelable { + + @NonNull + public static final Creator<Item> CREATOR = + new Creator<>() { + @Override + public Item createFromParcel(Parcel in) { + return new Item(in); + } + + @Override + public Item[] newArray(int size) { + return new Item[size]; + } + }; + + @NonNull private final String mRouteId; + + /** + * Creates an instance with the given value. + * + * @param routeId See {@link #getRouteId()}. Must not be empty. + */ + public Item(@NonNull String routeId) { + Preconditions.checkArgument(!TextUtils.isEmpty(routeId)); + mRouteId = routeId; + } + + private Item(Parcel in) { + String routeId = in.readString(); + Preconditions.checkArgument(!TextUtils.isEmpty(routeId)); + mRouteId = routeId; + } + + /** Returns the id of the route that corresponds to this route listing preference item. */ + @NonNull + public String getRouteId() { + return mRouteId; + } + + // Item Parcelable implementation. + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(mRouteId); + } + + // Equals and hashCode. + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Item)) { + return false; + } + Item item = (Item) other; + return mRouteId.equals(item.mRouteId); + } + + @Override + public int hashCode() { + return Objects.hash(mRouteId); + } + } +} diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java index 10973abf9c56..0982132e006d 100644 --- a/media/java/android/media/RoutingSessionInfo.java +++ b/media/java/android/media/RoutingSessionInfo.java @@ -25,6 +25,8 @@ import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; +import com.android.internal.util.Preconditions; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; @@ -106,9 +108,9 @@ public final class RoutingSessionInfo implements Parcelable { } RoutingSessionInfo(@NonNull Parcel src) { - Objects.requireNonNull(src, "src must not be null."); + mId = src.readString(); + Preconditions.checkArgument(!TextUtils.isEmpty(mId)); - mId = ensureString(src.readString()); mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src); mOwnerPackageName = src.readString(); mClientPackageName = ensureString(src.readString()); @@ -177,7 +179,7 @@ public final class RoutingSessionInfo implements Parcelable { */ @NonNull public String getId() { - if (mProviderId != null) { + if (!TextUtils.isEmpty(mProviderId)) { return MediaRouter2Utils.toUniqueId(mProviderId, mId); } else { return mId; @@ -421,7 +423,7 @@ public final class RoutingSessionInfo implements Parcelable { } // mProviderId can be null if not set. Return the original list for this case. - if (mProviderId == null) { + if (TextUtils.isEmpty(mProviderId)) { return routeIds; } diff --git a/media/java/android/media/VolumeInfo.java b/media/java/android/media/VolumeInfo.java index 6b4f604025e2..afb44bbb8b56 100644 --- a/media/java/android/media/VolumeInfo.java +++ b/media/java/android/media/VolumeInfo.java @@ -28,7 +28,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; -import java.util.List; import java.util.Objects; /** @@ -36,33 +35,36 @@ import java.util.Objects; * A class to represent volume information. * Can be used to represent volume associated with a stream type or {@link AudioVolumeGroup}. * Volume index is optional when used to represent a category of volume. - * Index ranges are supported too, making the representation of volume changes agnostic to the - * range (e.g. can be used to map BT A2DP absolute volume range to internal range). + * Volume ranges are supported too, making the representation of volume changes agnostic regarding + * the range of values that are supported (e.g. can be used to map BT A2DP absolute volume range to + * internal range). */ @SystemApi public final class VolumeInfo implements Parcelable { private static final String TAG = "VolumeInfo"; private final boolean mUsesStreamType; // false implies AudioVolumeGroup is used + private final boolean mHasMuteCommand; private final boolean mIsMuted; private final int mVolIndex; private final int mMinVolIndex; private final int mMaxVolIndex; - private final int mVolGroupId; - private final int mStreamType; + private final @Nullable AudioVolumeGroup mVolGroup; + private final @AudioManager.PublicStreamTypes int mStreamType; private static IAudioService sService; private static VolumeInfo sDefaultVolumeInfo; - private VolumeInfo(boolean usesStreamType, boolean isMuted, int volIndex, - int minVolIndex, int maxVolIndex, - int volGroupId, int streamType) { + private VolumeInfo(boolean usesStreamType, boolean hasMuteCommand, boolean isMuted, + int volIndex, int minVolIndex, int maxVolIndex, + AudioVolumeGroup volGroup, int streamType) { mUsesStreamType = usesStreamType; + mHasMuteCommand = hasMuteCommand; mIsMuted = isMuted; mVolIndex = volIndex; mMinVolIndex = minVolIndex; mMaxVolIndex = maxVolIndex; - mVolGroupId = volGroupId; + mVolGroup = volGroup; mStreamType = streamType; } @@ -79,8 +81,10 @@ public final class VolumeInfo implements Parcelable { /** * Returns the associated stream type, or will throw if {@link #hasStreamType()} returned false. * @return a stream type value, see AudioManager.STREAM_* + * @throws IllegalStateException when called on a VolumeInfo not configured for + * stream types. */ - public int getStreamType() { + public @AudioManager.PublicStreamTypes int getStreamType() { if (!mUsesStreamType) { throw new IllegalStateException("VolumeInfo doesn't use stream types"); } @@ -99,24 +103,28 @@ public final class VolumeInfo implements Parcelable { /** * Returns the associated volume group, or will throw if {@link #hasVolumeGroup()} returned * false. - * @return the volume group corresponding to this VolumeInfo, or null if an error occurred - * in the volume group management + * @return the volume group corresponding to this VolumeInfo + * @throws IllegalStateException when called on a VolumeInfo not configured for + * volume groups. */ - public @Nullable AudioVolumeGroup getVolumeGroup() { + public @NonNull AudioVolumeGroup getVolumeGroup() { if (mUsesStreamType) { throw new IllegalStateException("VolumeInfo doesn't use AudioVolumeGroup"); } - List<AudioVolumeGroup> volGroups = AudioVolumeGroup.getAudioVolumeGroups(); - for (AudioVolumeGroup group : volGroups) { - if (group.getId() == mVolGroupId) { - return group; - } - } - return null; + return mVolGroup; + } + + /** + * Return whether this instance is conveying a mute state + * @return true if the muted state was explicitly set for this instance + */ + public boolean hasMuteCommand() { + return mHasMuteCommand; } /** - * Returns whether this instance is conveying a mute state. + * Returns whether this instance is conveying a mute state that was explicitly set + * by {@link Builder#setMuted(boolean)}, false otherwise * @return true if the volume state is muted */ public boolean isMuted() { @@ -183,18 +191,21 @@ public final class VolumeInfo implements Parcelable { */ public static final class Builder { private boolean mUsesStreamType = true; // false implies AudioVolumeGroup is used - private int mStreamType = AudioManager.STREAM_MUSIC; + private @AudioManager.PublicStreamTypes int mStreamType = AudioManager.STREAM_MUSIC; + private boolean mHasMuteCommand = false; private boolean mIsMuted = false; private int mVolIndex = INDEX_NOT_SET; private int mMinVolIndex = INDEX_NOT_SET; private int mMaxVolIndex = INDEX_NOT_SET; - private int mVolGroupId = -Integer.MIN_VALUE; + private @Nullable AudioVolumeGroup mVolGroup; /** * Builder constructor for stream type-based VolumeInfo */ - public Builder(int streamType) { - // TODO validate stream type + public Builder(@AudioManager.PublicStreamTypes int streamType) { + if (!AudioManager.isPublicStreamType(streamType)) { + throw new IllegalArgumentException("Not a valid public stream type " + streamType); + } mUsesStreamType = true; mStreamType = streamType; } @@ -206,7 +217,7 @@ public final class VolumeInfo implements Parcelable { Objects.requireNonNull(volGroup); mUsesStreamType = false; mStreamType = -Integer.MIN_VALUE; - mVolGroupId = volGroup.getId(); + mVolGroup = volGroup; } /** @@ -217,11 +228,12 @@ public final class VolumeInfo implements Parcelable { Objects.requireNonNull(info); mUsesStreamType = info.mUsesStreamType; mStreamType = info.mStreamType; + mHasMuteCommand = info.mHasMuteCommand; mIsMuted = info.mIsMuted; mVolIndex = info.mVolIndex; mMinVolIndex = info.mMinVolIndex; mMaxVolIndex = info.mMaxVolIndex; - mVolGroupId = info.mVolGroupId; + mVolGroup = info.mVolGroup; } /** @@ -230,6 +242,7 @@ public final class VolumeInfo implements Parcelable { * @return the same builder instance */ public @NonNull Builder setMuted(boolean isMuted) { + mHasMuteCommand = true; mIsMuted = isMuted; return this; } @@ -239,7 +252,6 @@ public final class VolumeInfo implements Parcelable { * @param volIndex a 0 or greater value, or {@link #INDEX_NOT_SET} if unknown * @return the same builder instance */ - // TODO should we allow muted true + volume index set? (useful when toggling mute on/off?) public @NonNull Builder setVolumeIndex(int volIndex) { if (volIndex != INDEX_NOT_SET && volIndex < 0) { throw new IllegalArgumentException("Volume index cannot be negative"); @@ -294,9 +306,9 @@ public final class VolumeInfo implements Parcelable { throw new IllegalArgumentException("Min volume index:" + mMinVolIndex + " greater than max index:" + mMaxVolIndex); } - return new VolumeInfo(mUsesStreamType, mIsMuted, + return new VolumeInfo(mUsesStreamType, mHasMuteCommand, mIsMuted, mVolIndex, mMinVolIndex, mMaxVolIndex, - mVolGroupId, mStreamType); + mVolGroup, mStreamType); } } @@ -304,8 +316,8 @@ public final class VolumeInfo implements Parcelable { // Parcelable @Override public int hashCode() { - return Objects.hash(mUsesStreamType, mStreamType, mIsMuted, - mVolIndex, mMinVolIndex, mMaxVolIndex, mVolGroupId); + return Objects.hash(mUsesStreamType, mHasMuteCommand, mStreamType, mIsMuted, + mVolIndex, mMinVolIndex, mMaxVolIndex, mVolGroup); } @Override @@ -316,19 +328,20 @@ public final class VolumeInfo implements Parcelable { VolumeInfo that = (VolumeInfo) o; return ((mUsesStreamType == that.mUsesStreamType) && (mStreamType == that.mStreamType) - && (mIsMuted == that.mIsMuted) - && (mVolIndex == that.mVolIndex) - && (mMinVolIndex == that.mMinVolIndex) - && (mMaxVolIndex == that.mMaxVolIndex) - && (mVolGroupId == that.mVolGroupId)); + && (mHasMuteCommand == that.mHasMuteCommand) + && (mIsMuted == that.mIsMuted) + && (mVolIndex == that.mVolIndex) + && (mMinVolIndex == that.mMinVolIndex) + && (mMaxVolIndex == that.mMaxVolIndex) + && Objects.equals(mVolGroup, that.mVolGroup)); } @Override public String toString() { return new String("VolumeInfo:" + (mUsesStreamType ? (" streamType:" + mStreamType) - : (" volGroupId" + mVolGroupId)) - + " muted:" + mIsMuted + : (" volGroup:" + mVolGroup)) + + (mHasMuteCommand ? (" muted:" + mIsMuted) : ("[no mute cmd]")) + ((mVolIndex != INDEX_NOT_SET) ? (" volIndex:" + mVolIndex) : "") + ((mMinVolIndex != INDEX_NOT_SET) ? (" min:" + mMinVolIndex) : "") + ((mMaxVolIndex != INDEX_NOT_SET) ? (" max:" + mMaxVolIndex) : "")); @@ -343,21 +356,29 @@ public final class VolumeInfo implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeBoolean(mUsesStreamType); dest.writeInt(mStreamType); + dest.writeBoolean(mHasMuteCommand); dest.writeBoolean(mIsMuted); dest.writeInt(mVolIndex); dest.writeInt(mMinVolIndex); dest.writeInt(mMaxVolIndex); - dest.writeInt(mVolGroupId); + if (!mUsesStreamType) { + mVolGroup.writeToParcel(dest, 0 /*ignored*/); + } } private VolumeInfo(@NonNull Parcel in) { mUsesStreamType = in.readBoolean(); mStreamType = in.readInt(); + mHasMuteCommand = in.readBoolean(); mIsMuted = in.readBoolean(); mVolIndex = in.readInt(); mMinVolIndex = in.readInt(); mMaxVolIndex = in.readInt(); - mVolGroupId = in.readInt(); + if (!mUsesStreamType) { + mVolGroup = AudioVolumeGroup.CREATOR.createFromParcel(in); + } else { + mVolGroup = null; + } } public static final @NonNull Parcelable.Creator<VolumeInfo> CREATOR = diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml index f51266c55a65..97cae3adc4d5 100644 --- a/packages/CompanionDeviceManager/res/values-af/strings.xml +++ b/packages/CompanionDeviceManager/res/values-af/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot jou <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string> <string name="chooser_title" msgid="2262294130493605839">"Kies \'n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om deur <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> bestuur te word"</string> - <string name="summary_watch" msgid="3002344206574997652">"Hierdie program is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met jou kennisgewings te hê, en sal toegang hê tot jou Foon-, SMS-, Kontakte-, Kalender- en Toestelle in die Omtrek-toestemming."</string> - <string name="permission_apps" msgid="6142133265286656158">"Programme"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stroom jou foon se programme"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot hierdie inligting op jou foon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot hierdie inligting op jou foon"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Kennisgewings"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kan alle kennisgewings lees, insluitend inligting soos kontakte, boodskappe en foto\'s"</string> - <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string> <string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Dit kan mikrofoon-, kamera- en liggingtoegang insluit, asook ander sensitiewe toestemmings op <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Jy kan hierdie toestemmings enige tyd verander in jou Instellings op <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Program-ikoon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Meer Inligting-knoppie"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string> + <string name="permission_notification" msgid="693762568127741203">"Kennisgewings"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kan alle kennisgewings lees, insluitend inligting soos kontakte, boodskappe en foto\'s"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml index 15b39d2143ab..476a25e4cc3b 100644 --- a/packages/CompanionDeviceManager/res/values-am/strings.xml +++ b/packages/CompanionDeviceManager/res/values-am/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> የእርስዎን <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> መሣሪያ እንዲደርስ ይፍቀዱለት"</string> <string name="profile_name_watch" msgid="576290739483672360">"ሰዓት"</string> <string name="chooser_title" msgid="2262294130493605839">"በ<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> የሚተዳደር <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string> - <string name="summary_watch" msgid="3002344206574997652">"የእርስዎን <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ለማስተዳደር ይህ መተግበሪያ ያስፈልጋል። <xliff:g id="APP_NAME">%2$s</xliff:g> ከማሳወቂያዎችዎ ጋር መስተጋብር እንዲፈጥር እና የእርስዎን ስልክ፣ ኤስኤምኤስ፣ እውቂያዎች፣ የቀን መቁጠሪያ፣ የጥሪ ምዝገባ ማስታወሻዎች እና በአቅራቢያ ያሉ የመሣሪያዎች ፈቃዶች እንዲደርስ ይፈቀድለታል።"</string> - <string name="permission_apps" msgid="6142133265286656158">"መተግበሪያዎች"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"የስልክዎን መተግበሪያዎች በዥረት ይልቀቁ"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ይህን መረጃ ከስልክዎ ላይ እንዲደርስ ይፍቀዱለት"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"ማሳወቂያዎች"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"እንደ እውቂያዎች፣ መልዕክቶች እና ፎቶዎች ያሉ መረጃዎችን ጨምሮ ሁሉንም ማሳወቂያዎች ማንበብ ይችላል"</string> - <string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> የስልክዎን ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string> <string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>ይህ የማይክሮፎን፣ የካሜራ እና የአካባቢ መዳረሻ እና ሌሎች በ<strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p> ላይ ያሉ አደገኛ ፈቃዶችን ሊያካትት ይችላል።እነዚህን ፈቃዶች በማንኛውም ጊዜ በ<strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>ላይ ቅንብሮችዎ ውስጥ መቀየር ይችላሉ።"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"የመተግበሪያ አዶ"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"የተጨማሪ መረጃ አዝራር"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string> + <string name="permission_notification" msgid="693762568127741203">"ማሳወቂያዎች"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"እንደ እውቂያዎች፣ መልዕክቶች እና ፎቶዎች ያሉ መረጃዎችን ጨምሮ ሁሉንም ማሳወቂያዎች ማንበብ ይችላል"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml index 13dcb69f76ba..d9ba55583b5d 100644 --- a/packages/CompanionDeviceManager/res/values-ar/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"الساعة"</string> <string name="chooser_title" msgid="2262294130493605839">"اختَر <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ليديرها تطبيق <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"هذا التطبيق مطلوب لإدارة <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. سيتم السماح لتطبيق <xliff:g id="APP_NAME">%2$s</xliff:g> بالتفاعل مع الإشعارات والوصول إلى أذونات الهاتف والرسائل القصيرة وجهات الاتصال والتقويم وسجلّات المكالمات والأجهزة المجاورة."</string> - <string name="permission_apps" msgid="6142133265286656158">"التطبيقات"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"بث تطبيقات هاتفك"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"يطلب تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> لمشاركة التطبيقات بين أجهزتك."</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"الإشعارات"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"يمكن لهذا الملف الشخصي قراءة جميع الإشعارات، بما في ذلك المعلومات، مثل جهات الاتصال والرسائل والصور."</string> - <string name="permission_storage" msgid="6831099350839392343">"الصور والوسائط"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"يطلب تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> للوصول إلى الصور والوسائط والإشعارات في هاتفك."</string> <string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>قد تتضمَّن هذه الأذونات الوصول إلى الميكروفون والكاميرا والموقع الجغرافي وغيرها من أذونات الوصول إلى المعلومات الحسّاسة على <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>يمكنك تغيير هذه الأذونات في أي وقت في إعداداتك على <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"رمز التطبيق"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"زر مزيد من المعلومات"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"الصور والوسائط"</string> + <string name="permission_notification" msgid="693762568127741203">"الإشعارات"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"يمكن لهذا الملف الشخصي قراءة جميع الإشعارات، بما في ذلك المعلومات، مثل جهات الاتصال والرسائل والصور."</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml index 9df589a4a4da..ef685e6a942f 100644 --- a/packages/CompanionDeviceManager/res/values-as/strings.xml +++ b/packages/CompanionDeviceManager/res/values-as/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> এক্সেছ কৰিবলৈ দিয়ক"</string> <string name="profile_name_watch" msgid="576290739483672360">"ঘড়ী"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>এ পৰিচালনা কৰিব লগা এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string> - <string name="summary_watch" msgid="3002344206574997652">"আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এই এপ্টোৰ আৱশ্যক। <xliff:g id="APP_NAME">%2$s</xliff:g>ক আপোনাৰ জাননী ব্যৱহাৰ কৰিবলৈ আৰু আপোনাৰ ফ’ন, এছএমএছ, সম্পৰ্ক ,কেলেণ্ডাৰ, কল লগ আৰু নিকটৱৰ্তী ডিভাইচৰ অনুমতি এক্সেছ কৰিবলৈ দিয়া হ’ব।"</string> - <string name="permission_apps" msgid="6142133265286656158">"এপ্"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"আপোনাৰ ফ’নৰ এপ্ ষ্ট্ৰীম কৰক"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"জাননী"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"সম্পৰ্কসূচী, বাৰ্তা আৰু ফট’ৰ দৰে তথ্যকে ধৰি আটাইবোৰ জাননী পঢ়িব পাৰে"</string> - <string name="permission_storage" msgid="6831099350839392343">"ফট’ আৰু মিডিয়া"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play সেৱা"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ফ’নৰ ফট’, মিডিয়া আৰু জাননী এক্সেছ কৰাৰ বাবে অনুৰোধ জনাইছে"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>ইয়াত <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>ত মাইক্ৰ’ফ’ন, কেমেৰা আৰু অৱস্থানৰ এক্সেছ আৰু অন্য সংবেদশীল অনুমতিসমূহ প্ৰদান কৰাটো অন্তৰ্ভুক্ত হ’ব পাৰে।</p> <p>আপুনি যিকোনো সময়তে <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>ত থকা আপোনাৰ ছেটিঙত এই অনুমতিসমূহ সলনি কৰিব পাৰে।</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"এপৰ চিহ্ন"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"অধিক তথ্যৰ বুটাম"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ফট’ আৰু মিডিয়া"</string> + <string name="permission_notification" msgid="693762568127741203">"জাননী"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"সম্পৰ্কসূচী, বাৰ্তা আৰু ফট’ৰ দৰে তথ্যকে ধৰি আটাইবোৰ জাননী পঢ়িব পাৰে"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml index 4ef3111c23ac..b303e0f5e46d 100644 --- a/packages/CompanionDeviceManager/res/values-az/strings.xml +++ b/packages/CompanionDeviceManager/res/values-az/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinin <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazınıza girişinə icazə verin"</string> <string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> tərəfindən idarə ediləcək <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string> - <string name="summary_watch" msgid="3002344206574997652">"Bu tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızı idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> bildirişlərinizə, Telefon, SMS, Kontaktlar, Təqvim, Zəng qeydləri və Yaxınlıqdakı cihaz icazələrinə giriş əldə edəcək."</string> - <string name="permission_apps" msgid="6142133265286656158">"Tətbiqlər"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun tətbiqlərini yayımlayın"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Bildirişlər"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Bütün bildirişləri, o cümlədən kontaktlar, mesajlar və fotolar kimi məlumatları oxuya bilər"</string> - <string name="permission_storage" msgid="6831099350839392343">"Foto və media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play xidmətləri"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string> <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Buraya <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> cihazındakı Mikrofon, Kamera və Məkana girişi və digər həssas icazələr daxil ola bilər.</p> <p>Bu icazələri istənilən vaxt <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> cihazında ayarlarınızda dəyişə bilərsiniz.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Tətbiq İkonası"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Ətraflı Məlumat Düyməsi"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Foto və media"</string> + <string name="permission_notification" msgid="693762568127741203">"Bildirişlər"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Bütün bildirişləri, o cümlədən kontaktlar, mesajlar və fotolar kimi məlumatları oxuya bilər"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml index baf55d2174b4..a06467257c12 100644 --- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"sat"</string> <string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ova aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa obaveštenjima i pristup dozvolama za telefon, SMS, kontakte, kalendar, evidencije poziva i uređaje u blizini."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Strimujte aplikacije na telefonu"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Obaveštenja"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Može da čita sva obaveštenja, uključujući informacije poput kontakata, poruka i slika"</string> - <string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string> <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>To može da obuhvata pristup mikrofonu, kameri i lokaciji, kao i drugim osetljivim dozvolama na uređaju <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>U svakom trenutku možete da promenite te dozvole u Podešavanjima na uređaju <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Dugme za više informacija"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string> + <string name="permission_notification" msgid="693762568127741203">"Obaveštenja"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Može da čita sva obaveštenja, uključujući informacije poput kontakata, poruka i slika"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml index 276127f6007d..a42b974beb17 100644 --- a/packages/CompanionDeviceManager/res/values-be/strings.xml +++ b/packages/CompanionDeviceManager/res/values-be/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ да вашай прылады <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"гадзіннік"</string> <string name="chooser_title" msgid="2262294130493605839">"Выберыце прыладу (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Гэта праграма неабходная для кіравання прыладай \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> зможа ўзаемадзейнічаць з вашымі апавяшчэннямі і атрымае доступ да тэлефона, SMS, кантактаў, календара, журналаў выклікаў і прылад паблізу."</string> - <string name="permission_apps" msgid="6142133265286656158">"Праграмы"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Трансліруйце змесціва праграм з вашага тэлефона"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> мець доступ да гэтай інфармацыі з вашага тэлефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на трансляцыю праграм паміж вашымі прыладамі"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> мець доступ да гэтай інфармацыі з вашага тэлефона"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Апавяшчэнні"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Можа счытваць усе апавяшчэнні, уключаючы паведамленні, фота і інфармацыю пра кантакты"</string> - <string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на доступ да фота, медыяфайлаў і апавяшчэнняў на вашым тэлефоне"</string> <string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Дазволы могуць уключаць доступ да мікрафона, камеры і даных пра месцазнаходжанне, а таксама да іншай канфідэнцыяльнай інфармацыі на прыладзе <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Вы можаце ў любы час змяніць гэтыя дазволы ў Наладах на прыладзе <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Значок праграмы"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Кнопка \"Даведацца больш\""</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string> + <string name="permission_notification" msgid="693762568127741203">"Апавяшчэнні"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Можа счытваць усе апавяшчэнні, уключаючы паведамленні, фота і інфармацыю пра кантакты"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml index 6b17ffd34ace..a4bd8548c293 100644 --- a/packages/CompanionDeviceManager/res/values-bg/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Разрешаване на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до устройството ви <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string> <string name="chooser_title" msgid="2262294130493605839">"Изберете устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), което да се управлява от <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Това приложение е необходимо за управление на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ще получи разрешение да взаимодейства с известията ви и да осъществява достъп до разрешенията за телефона, SMS съобщенията, контактите, календара, списъците с обажданията и разрешенията за устройства в близост."</string> - <string name="permission_apps" msgid="6142133265286656158">"Приложения"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Поточно предаване на приложенията на телефона ви"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Известия"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Може да чете всички известия, включително различна информация, като например контакти, съобщения и снимки"</string> - <string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за достъп до снимките, мултимедията и известията на телефона ви"</string> <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Това може да включва достъп до микрофона, камерата и местоположението, както и други разрешения за достъп до поверителна информация на <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Можете да промените тези разрешения по всяко време от настройките на <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Икона на приложението"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Бутон за още информация"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string> + <string name="permission_notification" msgid="693762568127741203">"Известия"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Може да чете всички известия, включително различна информация, като например контакти, съобщения и снимки"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml index 1eaf1424ed91..2f36c5a7c0c4 100644 --- a/packages/CompanionDeviceManager/res/values-bn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"আপনার <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> অ্যাক্সেস করার জন্য <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-কে অনুমতি দিন"</string> <string name="profile_name_watch" msgid="576290739483672360">"ঘড়ি"</string> <string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন যেটি <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ম্যানেজ করবে"</string> - <string name="summary_watch" msgid="3002344206574997652">"এই অ্যাপকে আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ম্যানেজ করতে দিতে হবে। <xliff:g id="APP_NAME">%2$s</xliff:g>-কে আপনার বিজ্ঞপ্তির সাথে ইন্টার্যাক্ট এবং ফোন, এসএমএস, পরিচিতি, ক্যালেন্ডার, কল লগ ও আশেপাশের ডিভাইস অ্যাক্সেস করার অনুমতি দেওয়া হবে।"</string> - <string name="permission_apps" msgid="6142133265286656158">"অ্যাপ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"আপনার ফোনের অ্যাপ স্ট্রিমিংয়ের মাধ্যমে কাস্ট করুন"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"আপনার ফোন থেকে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-কে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"বিজ্ঞপ্তি"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"সব বিজ্ঞপ্তি পড়তে পারবে, যার মধ্যে পরিচিতি, মেসেজ ও ফটোর মতো তথ্য অন্তর্ভুক্ত"</string> - <string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>এটি <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p&gt-এ হয়ত মাইক্রোফোন, ক্যামেরা এবং লোকেশনের অ্যাক্সেস ও অন্যান্য সংবেদনশীল অনুমতি অন্তর্ভুক্ত করতে পারে;আপনি যেকোনও সময় <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>-এর \'সেটিংস\'-এ গিয়ে এইসব অনুমতি পরিবর্তন করতে পারবেন"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"অ্যাপের আইকন"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"আরও তথ্য সংক্রান্ত বোতাম"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string> + <string name="permission_notification" msgid="693762568127741203">"বিজ্ঞপ্তি"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"সব বিজ্ঞপ্তি পড়তে পারবে, যার মধ্যে পরিচিতি, মেসেজ ও ফটোর মতো তথ্য অন্তর্ভুক্ত"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml index 8c941accbe40..78f6e2ce99ef 100644 --- a/packages/CompanionDeviceManager/res/values-bs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Dozvolite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"sat"</string> <string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ova aplikacija je potrebna za upravljanje profilom: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> će se dozvoliti da ostvari interakciju s vašim obavještenjima i da pristupi odobrenjima za Telefon, SMS, Kontakte, Kalendar, Zapisnike poziva i Uređaje u blizini."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Prenosite aplikacije s telefona"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama s telefona"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Dozvolite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa ovim informacijama s vašeg telefona"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Obavještenja"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sva obavještenja, uključujući informacije kao što su kontakti, poruke i fotografije"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string> <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Ovo može uključivati pristup mikrofonu, kameri i lokaciji i druga osjetljiva odobrenja na uređaju <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Uvijek možete promijeniti ova odobrenja u Postavkama na uređaju <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Dugme Više informacija"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string> + <string name="permission_notification" msgid="693762568127741203">"Obavještenja"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sva obavještenja, uključujući informacije kao što su kontakti, poruke i fotografije"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml index 5cc72ae55e74..840c89c65f5c 100644 --- a/packages/CompanionDeviceManager/res/values-ca/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"rellotge"</string> <string name="chooser_title" msgid="2262294130493605839">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> perquè el gestioni <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Aquesta aplicació es necessita per gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per interaccionar amb les teves notificacions i accedir al telèfon, als SMS, als contactes, al calendari, als registres de trucades i als dispositius propers."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplicacions"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Reprodueix en continu aplicacions del telèfon"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a aquesta informació del telèfon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> per reproduir en continu aplicacions entre els dispositius"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a aquesta informació del telèfon"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificacions"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Pot llegir totes les notificacions, inclosa informació com ara els contactes, els missatges i les fotos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> per accedir a les fotos, el contingut multimèdia i les notificacions del telèfon"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Això pot incloure accés al micròfon, a la càmera i a la ubicació, i altres permisos sensibles a <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Pots canviar aquests permisos en qualsevol moment a <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>, a Configuració.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Icona de l\'aplicació"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Botó Més informació"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificacions"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Pot llegir totes les notificacions, inclosa informació com ara els contactes, els missatges i les fotos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml index 0d445287ef58..0ce29cf45703 100644 --- a/packages/CompanionDeviceManager/res/values-cs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Povolit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k vašemu zařízení <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string> <string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Tato aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s vašimi oznámeními a získá přístup k telefonu, SMS, kontaktům, kalendáři, seznamům hovorů a zařízením v okolí."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikace"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikace v telefonu"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Oznámení"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Může číst veškerá oznámení včetně informací, jako jsou kontakty, zprávy a fotky"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string> <string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Může být zahrnut přístup k mikrofonu, fotoaparátu a poloze a další citlivá oprávnění na zařízení <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Tato oprávnění můžete v Nastavení na zařízení <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> kdykoliv změnit.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikace"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Tlačítko Další informace"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string> + <string name="permission_notification" msgid="693762568127741203">"Oznámení"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Může číst veškerá oznámení včetně informací, jako jsou kontakty, zprávy a fotky"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml index a043978f3de1..32f958febe28 100644 --- a/packages/CompanionDeviceManager/res/values-da/strings.xml +++ b/packages/CompanionDeviceManager/res/values-da/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Tillad, at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> får adgang til dit <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"ur"</string> <string name="chooser_title" msgid="2262294130493605839">"Vælg den enhed (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), som skal administreres af <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Du skal bruge denne app for at administrere dit <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilladelse til at interagere med dine notifikationer og får adgang til dine tilladelser Opkald, Sms, Kalender, Opkaldshistorik og Enheder i nærheden."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stream din telefons apps"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Giv <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adgang til disse oplysninger fra din telefon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Tillad, at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> får adgang til disse oplysninger fra din telefon"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifikationer"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kan læse alle notifikationer, herunder oplysninger som f.eks. kontakter, beskeder og billeder"</string> - <string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string> <string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Dette kan omfatte mikrofon-, kamera- og lokationsadgang samt andre tilladelser til at tilgå følsomme oplysninger på <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Du kan til enhver tid ændre disse tilladelser under Indstillinger på <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Appikon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Knappen Flere oplysninger"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifikationer"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kan læse alle notifikationer, herunder oplysninger som f.eks. kontakter, beskeder og billeder"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml index 77fb0bc92fcc..42c6fdec170b 100644 --- a/packages/CompanionDeviceManager/res/values-de/strings.xml +++ b/packages/CompanionDeviceManager/res/values-de/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> erlauben, auf dein Gerät (<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>) zuzugreifen"</string> <string name="profile_name_watch" msgid="576290739483672360">"Smartwatch"</string> <string name="chooser_title" msgid="2262294130493605839">"Gerät „<xliff:g id="PROFILE_NAME">%1$s</xliff:g>“ auswählen, das von <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> verwaltet werden soll"</string> - <string name="summary_watch" msgid="3002344206574997652">"Diese App wird zur Verwaltung des Geräts „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“ benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf mit deinen Benachrichtigungen interagieren und auf die Berechtigungen für „Telefon“, „SMS“, „Kontakte“, „Kalender“, „Anrufliste“ und „Geräte in der Nähe“ zugreifen."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Smartphone-Apps streamen"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Benachrichtigungen"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kann alle Benachrichtigungen lesen, einschließlich Informationen wie Kontakten, Nachrichten und Fotos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string> <string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Dazu können Berechtigungen für Mikrofon, Kamera und Standortzugriff sowie andere vertrauliche Berechtigungen auf <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> gehören.</p><p>Sie lassen sich jederzeit in den Einstellungen auf <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> ändern.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"App-Symbol"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Weitere-Infos-Schaltfläche"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</string> + <string name="permission_notification" msgid="693762568127741203">"Benachrichtigungen"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kann alle Benachrichtigungen lesen, einschließlich Informationen wie Kontakten, Nachrichten und Fotos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml index 56d7dcde2a61..28ab7a31d19b 100644 --- a/packages/CompanionDeviceManager/res/values-el/strings.xml +++ b/packages/CompanionDeviceManager/res/values-el/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Επιτρέψτε στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να έχει πρόσβαση στη συσκευή <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"ρολόι"</string> <string name="chooser_title" msgid="2262294130493605839">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για διαχείριση από την εφαρμογή <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Αυτή η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Η εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> θα επιτρέπεται να αλληλεπιδρά με τις ειδοποιήσεις και να έχει πρόσβαση στις άδειες Τηλέφωνο, SMS, Επαφές, Ημερολόγιο, Αρχεία καταγραφής κλήσεων και Συσκευές σε κοντινή απόσταση."</string> - <string name="permission_apps" msgid="6142133265286656158">"Εφαρμογές"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Επιτρέψτε στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να έχει πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Ειδοποιήσεις"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Μπορεί να διαβάσει όλες τις ειδοποιήσεις, συμπεριλαμβανομένων πληροφοριών όπως επαφές, μηνύματα και φωτογραφίες"</string> - <string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string> <string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Αυτές μπορεί να περιλαμβάνουν πρόσβαση σε μικρόφωνο, κάμερα και τοποθεσία και άλλες άδειες πρόσβασης σε ευαίσθητες πληροφορίες στη συσκευή <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Μπορείτε να αλλάξετε αυτές τις άδειες ανά πάσα στιγμή στις Ρυθμίσεις σας στη συσκευή <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Εικονίδιο εφαρμογής"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Κουμπί περισσότερων πληροφορ."</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string> + <string name="permission_notification" msgid="693762568127741203">"Ειδοποιήσεις"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Μπορεί να διαβάσει όλες τις ειδοποιήσεις, συμπεριλαμβανομένων πληροφοριών όπως επαφές, μηνύματα και φωτογραφίες"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml index c80620ebad86..89aebbd208cf 100644 --- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access your <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, calendar, call logs and Nearby devices permissions."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>This may include microphone, camera and location access, and other sensitive permissions on <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>You can change these permissions at any time in your settings on <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"App icon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"More information button"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml index 398280922cc5..d6f95ad9cf08 100644 --- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access your <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages, and photos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media, and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>This may include Microphone, Camera, and Location access, and other sensitive permissions on <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>You can change these permissions any time in your Settings on <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"App Icon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"More Information Button"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages, and photos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml index c80620ebad86..89aebbd208cf 100644 --- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access your <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, calendar, call logs and Nearby devices permissions."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>This may include microphone, camera and location access, and other sensitive permissions on <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>You can change these permissions at any time in your settings on <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"App icon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"More information button"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml index c80620ebad86..89aebbd208cf 100644 --- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access your <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, calendar, call logs and Nearby devices permissions."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>This may include microphone, camera and location access, and other sensitive permissions on <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>You can change these permissions at any time in your settings on <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"App icon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"More information button"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml index 1b8833bd60cb..54c4931237a4 100644 --- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access your <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages, and photos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media, and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>This may include Microphone, Camera, and Location access, and other sensitive permissions on <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>You can change these permissions any time in your Settings on <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"App Icon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"More Information Button"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages, and photos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml index b7511ba79e16..31e9b6650166 100644 --- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a tu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string> <string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para que la app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> lo administre"</string> - <string name="summary_watch" msgid="3002344206574997652">"Esta app es necesaria para administrar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a los permisos de Teléfono, SMS, Contactos, Calendario, Llamadas y Dispositivos cercanos."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Transmitir las apps de tu teléfono"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir apps entre dispositivos"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluso con información como contactos, mensajes y fotos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, el contenido multimedia y las notificaciones de tu teléfono"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Esto puede incluir el acceso al micrófono, la cámara y la ubicación, así como otros permisos sensibles del dispositivo <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Puedes cambiar estos permisos en cualquier momento en la Configuración del dispositivo <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ícono de la app"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Botón Más información"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluso con información como contactos, mensajes y fotos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml index 11ed3c338e48..bcfff13272ae 100644 --- a/packages/CompanionDeviceManager/res/values-es/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a tu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string> <string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para gestionarlo con <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Se necesita esta aplicación para gestionar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a tus permisos de teléfono, SMS, contactos, calendario, registros de llamadas y dispositivos cercanos."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplicaciones"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Proyecta aplicaciones de tu teléfono"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluida información como contactos, mensajes y fotos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, los archivos multimedia y las notificaciones de tu teléfono"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Esto puede incluir acceso al micrófono, la cámara y la ubicación, así como otros permisos sensibles de <p><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Puedes cambiar estos permisos cuando quieras en los ajustes de <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>."</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Icono de la aplicación"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Botón Más información"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluida información como contactos, mensajes y fotos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml index 40a55b5e2215..b267ce544c8f 100644 --- a/packages/CompanionDeviceManager/res/values-et/strings.xml +++ b/packages/CompanionDeviceManager/res/values-et/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> teie seadmele <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> juurde pääseda"</string> <string name="profile_name_watch" msgid="576290739483672360">"käekell"</string> <string name="chooser_title" msgid="2262294130493605839">"Valige seade <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Seda rakendust on vaja teie profiili <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse kasutada teie märguandeid ja pääseda juurde teie telefoni, SMS-ide, kontaktide, kalendri, kõnelogide ja läheduses olevate seadmete lubadele."</string> - <string name="permission_apps" msgid="6142133265286656158">"Rakendused"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Telefoni rakenduste voogesitamine"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Märguanded"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kõikide märguannete, sealhulgas teabe, nagu kontaktid, sõnumid ja fotod, lugemine"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string> <string name="profile_name_generic" msgid="6851028682723034988">"seade"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>See võib hõlmata mikrofoni, kaamerat ja juurdepääsu asukohale ning muid tundlikke lube seadmes <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Võite neid lube seadme <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> seadetes igal ajal muuta.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Rakenduse ikoon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Nupp Lisateave"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string> + <string name="permission_notification" msgid="693762568127741203">"Märguanded"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kõikide märguannete, sealhulgas teabe, nagu kontaktid, sõnumid ja fotod, lugemine"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml index 83d0e02a5566..3140762f181d 100644 --- a/packages/CompanionDeviceManager/res/values-eu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Eman <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> atzitzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string> <string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string> <string name="chooser_title" msgid="2262294130493605839">"Aukeratu <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> aplikazioak kudeatu beharreko <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> - <string name="summary_watch" msgid="3002344206574997652">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko beharrezkoa da aplikazio hau. Jakinarazpenekin interakzioan aritzeko eta telefonoa, SMSak, kontaktuak, egutegia, deien erregistroa eta inguruko gailuak atzitzeko baimenak izango ditu <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikazioak"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Igorri zuzenean telefonoko aplikazioak"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu baterako baino gehiagotarako zerbitzuak"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Eman telefonoko informazio hau atzitzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Jakinarazpenak"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Jakinarazpen guztiak irakur ditzake; besteak beste, kontaktuak, mezuak, argazkiak eta antzeko informazioa"</string> - <string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak atzitzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string> <string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Haien artean, baliteke <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> gailuaren mikrofonoa, kamera, kokapenerako sarbidea eta beste kontuzko baimen batzuk egotea.</p> <p>Baimen horiek edonoiz alda ditzakezu <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> gailuaren ezarpenetan.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Aplikazioaren ikonoa"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Informazio gehiagorako botoia"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string> + <string name="permission_notification" msgid="693762568127741203">"Jakinarazpenak"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Jakinarazpen guztiak irakur ditzake; besteak beste, kontaktuak, mezuak, argazkiak eta antzeko informazioa"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml index 263f3ea618b6..b6421b3646e7 100644 --- a/packages/CompanionDeviceManager/res/values-fa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه دهید به <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> دسترسی داشته باشد"</string> <string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string> <string name="chooser_title" msgid="2262294130493605839">"انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای مدیریت کردن با <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما لازم است. <xliff:g id="APP_NAME">%2$s</xliff:g> میتواند با اعلانهای شما تعامل داشته باشد و به اجازههای «تلفن»، «پیامک»، «مخاطبین»، «تقویم»، «گزارشهای تماس» و «دستگاههای اطراف» دسترسی خواهد داشت."</string> - <string name="permission_apps" msgid="6142133265286656158">"برنامهها"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"جاریسازی برنامههای تلفن"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"اجازه دادن به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> برای دسترسی به اطلاعات تلفن"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویسهای بیندستگاهی"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه میخواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامهها را بین دستگاههای شما جاریسازی کند"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه دسترسی به این اطلاعات در دستگاهتان داده شود"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"اعلانها"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"میتواند همه اعلانها، ازجمله اطلاعاتی مثل مخاطبین، پیامها، و عکسها را بخواند"</string> - <string name="permission_storage" msgid="6831099350839392343">"عکسها و رسانهها"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه میخواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> به عکسها، رسانهها، و اعلانهای تلفن شما دسترسی پیدا کند"</string> <string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>این اجازهها میتواند شامل دسترسی به «میکروفون»، «دوربین»، و «مکان»، و دیگر اجازههای حساس در <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> شود.</p> <p>هروقت بخواهید میتوانید این اجازهها را در «تنظیمات» در <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> تغییر دهید.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"نماد برنامه"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"دکمه اطلاعات بیشتر"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"عکسها و رسانهها"</string> + <string name="permission_notification" msgid="693762568127741203">"اعلانها"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"میتواند همه اعلانها، ازجمله اطلاعاتی مثل مخاطبین، پیامها، و عکسها را بخواند"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml index 67252c501b66..d71ad89da69b 100644 --- a/packages/CompanionDeviceManager/res/values-fi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Salli, että <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saa pääsyn laitteeseesi: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"kello"</string> <string name="chooser_title" msgid="2262294130493605839">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, jota <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> hallinnoi"</string> - <string name="summary_watch" msgid="3002344206574997652">"Profiilin (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) ylläpitoon tarvitaan tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa luvan hallinnoida ilmoituksiasi sekä pääsyn puhelimeen, tekstiviesteihin, yhteystietoihin, kalenteriin, puhelulokeihin ja lähellä olevat laitteet ‑lupiin."</string> - <string name="permission_apps" msgid="6142133265286656158">"Sovellukset"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Striimaa puhelimen sovelluksia"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Salli, että <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saa pääsyn näihin puhelimesi tietoihin"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia laitteidesi välillä"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Salli pääsy tähän tietoon puhelimellasi: <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Ilmoitukset"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Voi lukea kaikkia ilmoituksia, esim. kontakteihin, viesteihin ja kuviin liittyviä tietoja"</string> - <string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string> <string name="profile_name_generic" msgid="6851028682723034988">"laite"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Tähän voi kuulua pääsy mikrofoniin, kameraan ja sijaintiin sekä muita arkaluontoisia lupia laitteella <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Voit muuttaa lupia asetuksista milloin tahansa laitteella <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Sovelluskuvake"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Lisätietopainike"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string> + <string name="permission_notification" msgid="693762568127741203">"Ilmoitukset"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Voi lukea kaikkia ilmoituksia, esim. kontakteihin, viesteihin ja kuviin liittyviä tietoja"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml index b85099ad2ca2..95f512a97969 100644 --- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à votre <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"montre"</string> <string name="chooser_title" msgid="2262294130493605839">"Choisissez un(e) <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Cette application est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec vos notifications et d\'accéder aux autorisations suivantes : téléphone, messages texte, contacts, agenda, journaux d\'appels et appareils à proximité."</string> - <string name="permission_apps" msgid="6142133265286656158">"Applications"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Diffusez les applications de votre téléphone"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Autorisez <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations à partir de votre téléphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorisez <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations à partir de votre téléphone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string> <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Cela peut comprendre l\'accès au microphone, à l\'appareil photo et à la position, ainsi que d\'autres autorisations sensibles sur <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Vous pouvez modifier ces autorisations en tout temps dans vos paramètres sur <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Icône de l\'application"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Bouton En savoir plus"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml index 8a13866a5a07..aa4da5b018d9 100644 --- a/packages/CompanionDeviceManager/res/values-fr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à votre <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"montre"</string> <string name="chooser_title" msgid="2262294130493605839">"Sélectionnez le/la <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Cette appli est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec vos notifications et d\'accéder au téléphone, aux SMS, aux contacts, à l\'agenda, aux journaux d\'appels et aux appareils à proximité."</string> - <string name="permission_apps" msgid="6142133265286656158">"Applis"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Diffuser en streaming les applis de votre téléphone"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations depuis votre téléphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations depuis votre téléphone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris des informations comme les contacts, messages et photos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string> <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Il peut s\'agir de l\'accès au micro, à l\'appareil photo et à la position, et d\'autres autorisations sensibles sur l\'appareil <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Vous pouvez modifier ces autorisations à tout moment dans les paramètres de l\'appareil <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Icône d\'application"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Bouton Plus d\'informations"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifications"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris des informations comme les contacts, messages et photos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml index 8134e6449a28..2a7af1877845 100644 --- a/packages/CompanionDeviceManager/res/values-gl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda ao teu dispositivo (<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>)"</string> <string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string> <string name="chooser_title" msgid="2262294130493605839">"Escolle un perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Esta aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar coas túas notificacións e acceder aos permisos do teu teléfono, das SMS, dos contactos, do calendario, dos rexistros de chamadas e dos dispositivos próximos."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplicacións"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Emite as aplicacións do teu teléfono"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde o teu teléfono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir contido de aplicacións entre os teus aparellos"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información do teu teléfono"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificacións"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificacións (que poden incluír información como contactos, mensaxes e fotos)"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para acceder ás fotos, ao contido multimedia e ás notificacións do teléfono"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Con esta acción podes conceder acceso ao micrófono, á cámara e á localización, así como outros permisos de acceso á información confidencial de <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Podes cambiar estes permisos en calquera momento na configuración de <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Icona de aplicación"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Botón de máis información"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificacións"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificacións (que poden incluír información como contactos, mensaxes e fotos)"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml index c6a8330b0482..6483d1b3ff12 100644 --- a/packages/CompanionDeviceManager/res/values-gu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"તમારા <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ને ઍક્સેસ કરવાની <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string> <string name="profile_name_watch" msgid="576290739483672360">"સ્માર્ટવૉચ"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> દ્વારા મેનેજ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string> - <string name="summary_watch" msgid="3002344206574997652">"તમારી <xliff:g id="DEVICE_NAME">%1$s</xliff:g> મેનેજ કરવા માટે આ ઍપ જરૂરી છે. <xliff:g id="APP_NAME">%2$s</xliff:g>ને તમારા નોટિફિકેશન સાથે ક્રિયાપ્રતિક્રિયા કરવાની તેમજ તમારો ફોન, SMS, સંપર્કો, કૅલેન્ડર, કૉલ લૉગ અને નજીકનાં ડિવાઇસની પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી આપવામાં આવશે."</string> - <string name="permission_apps" msgid="6142133265286656158">"ઍપ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"તમારા ફોનની ઍપ સ્ટ્રીમ કરો"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"નોટિફિકેશન"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"સંપર્કો, મેસેજ અને ફોટા જેવી માહિતી સહિતના બધા નોટિફિકેશન વાંચી શકે છે"</string> - <string name="permission_storage" msgid="6831099350839392343">"ફોટા અને મીડિયા"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play સેવાઓ"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ફોનના ફોટા, મીડિયા અને નોટિફિકેશન ઍક્સેસ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>આમાં <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> પરના માઇક્રોફોન, કૅમેરા અને સ્થાનના ઍક્સેસ તથા અન્ય સંવેદનશીલ માહિતીની પરવાનગીઓ શામેલ હોઈ શકે છે.</p> <p>તમે <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> પર તમારા સેટિંગમાં તમે કોઈપણ સમયે આ પરવાનગીઓને બદલી શકો છો.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ઍપનું આઇકન"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"વધુ માહિતી માટેનું બટન"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ફોટા અને મીડિયા"</string> + <string name="permission_notification" msgid="693762568127741203">"નોટિફિકેશન"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"સંપર્કો, મેસેજ અને ફોટા જેવી માહિતી સહિતના બધા નોટિફિકેશન વાંચી શકે છે"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml index c4ca37c6ae72..978e333c6a14 100644 --- a/packages/CompanionDeviceManager/res/values-hi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ऐक्सेस करने की अनुमति दें"</string> <string name="profile_name_watch" msgid="576290739483672360">"स्मार्टवॉच"</string> <string name="chooser_title" msgid="2262294130493605839">"कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें, ताकि उसे <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> की मदद से मैनेज किया जा सके"</string> - <string name="summary_watch" msgid="3002344206574997652">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g> आपकी सूचनाओं पर कार्रवाई कर पाएगा. साथ ही, इसे आपके फ़ोन, एसएमएस, संपर्कों, कैलेंडर, कॉल लॉग, और आस-पास मौजूद डिवाइसों को ऐक्सेस करने की अनुमति मिल पाएगी."</string> - <string name="permission_apps" msgid="6142133265286656158">"ऐप्लिकेशन"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"अपने फ़ोन के ऐप्लिकेशन को स्ट्रीम करें"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, आपके डिवाइसों के बीच ऐप्लिकेशन को स्ट्रीम करने की अनुमति मांग रहा है"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"सूचनाएं"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"इससे सभी सूचनाएं देखी जा सकती हैं. इनमें संपर्क, मैसेज, और फ़ोटो जैसी जानकारी शामिल होती है"</string> - <string name="permission_storage" msgid="6831099350839392343">"फ़ोटो और मीडिया"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, फ़ोन में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रहा है"</string> <string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>इसमें <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> पर मौजूद माइक्रोफ़ोन, कैमरा, जगह की जानकारी को ऐक्सेस करने, और अन्य संवेदनशील जानकारी ऐक्सेस करने की अनुमतियां शामिल हो सकती हैं.</p> <p>किसी भी समय <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> की सेटिंग में जाकर, इन अनुमतियों में बदलाव किए जा सकते हैं.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ऐप्लिकेशन आइकॉन"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"ज़्यादा जानकारी वाला बटन"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"फ़ोटो और मीडिया"</string> + <string name="permission_notification" msgid="693762568127741203">"सूचनाएं"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"इससे सभी सूचनाएं देखी जा सकती हैं. इनमें संपर्क, मैसेज, और फ़ोटो जैसी जानकारी शामिल होती है"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml index 0c6d3a224395..a9895ebc2250 100644 --- a/packages/CompanionDeviceManager/res/values-hr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Dopustite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa vašem uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"satom"</string> <string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ta je aplikacija potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s vašim obavijestima i pristupati dopuštenjima za telefon, SMS-ove, kontakte, kalendar, zapisnike poziva i uređaje u blizini."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikacija vašeg telefona"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa informacijama s vašeg telefona"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za emitiranje aplikacija između vaših uređaja"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Omogućite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa informacijama s vašeg telefona"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Obavijesti"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sve obavijesti, uključujući informacije kao što su kontakti, poruke i fotografije"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string> <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>To može uključivati pristup mikrofonu, kameri i lokaciji i druga dopuštenja za osjetljive podatke na uređaju <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Ta dopuštenja uvijek možete promijeniti u postavkama na uređaju <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Gumb Više informacija"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string> + <string name="permission_notification" msgid="693762568127741203">"Obavijesti"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sve obavijesti, uključujući informacije kao što su kontakti, poruke i fotografije"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml index ac458b377d36..83f681aa8fd9 100644 --- a/packages/CompanionDeviceManager/res/values-hu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"A(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> hozzáférésének engedélyezése a(z) <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> eszközhöz"</string> <string name="profile_name_watch" msgid="576290739483672360">"óra"</string> <string name="chooser_title" msgid="2262294130493605839">"A(z) <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> alkalmazással kezelni kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiválasztása"</string> - <string name="summary_watch" msgid="3002344206574997652">"Szükség van erre az alkalmazásra a következő kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> műveleteket végezhet majd az értesítésekkel, és hozzáférhet a telefonra, az SMS-ekre, a névjegyekre, a naptárra, a hívásnaplókra és a közeli eszközökre vonatkozó engedélyekhez."</string> - <string name="permission_apps" msgid="6142133265286656158">"Alkalmazások"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"A telefon alkalmazásainak streamelése"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Értesítések"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Elolvashat minden értesítést, ideértve az olyan információkat, mint a névjegyek, az üzenetek és a fotók"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében a telefonon tárolt fotókhoz, médiatartalmakhoz és értesítésekhez való hozzáféréshez"</string> <string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Ide tartozhatnak a mikrofonhoz, a kamerához és a helyhez való hozzáférések, valamint a(z) <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> eszközön érvényes egyéb, bizalmas adatokra vonatkozó hozzáférési engedélyek is.</p> <p>Ezeket az engedélyeket bármikor módosíthatja a(z) <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> eszköz beállításai között.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Alkalmazás ikonja"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"További információ gomb"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string> + <string name="permission_notification" msgid="693762568127741203">"Értesítések"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Elolvashat minden értesítést, ideértve az olyan információkat, mint a névjegyek, az üzenetek és a fotók"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml index b4b29cb05f2a..d0b739d0f7cf 100644 --- a/packages/CompanionDeviceManager/res/values-hy/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին կառավարել ձեր <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> սարքը"</string> <string name="profile_name_watch" msgid="576290739483672360">"ժամացույց"</string> <string name="chooser_title" msgid="2262294130493605839">"Ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը, որը պետք է կառավարվի <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> հավելվածի կողմից"</string> - <string name="summary_watch" msgid="3002344206574997652">"Այս հավելվածն անհրաժեշտ է ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքը կառավարելու համար։ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածը կկարողանա փոխազդել ձեր ծանուցումների հետ և կստանա «Հեռախոս», «SMS», «Կոնտակտներ», «Օրացույց», «Կանչերի ցուցակ» և «Մոտակա սարքեր» թույլտվությունները։"</string> - <string name="permission_apps" msgid="6142133265286656158">"Հավելվածներ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Հեռարձակել հեռախոսի հավելվածները"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Ծանուցումներ"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Կարող է կարդալ բոլոր ծանուցումները, ներառյալ տեղեկությունները, օրինակ՝ կոնտակտները, հաղորդագրությունները և լուսանկարները"</string> - <string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string> <string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Դրանք կարող են ներառել խոսափողի, տեսախցիկի և տեղադրության տվյալների օգտագործման թույլտվությունները, ինչպես նաև կոնֆիդենցիալ տեղեկությունների օգտագործման այլ թույլտվություններ <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> սարքում։</p> <p>Այդ թույլտվությունները ցանկացած ժամանակ կարելի է փոխել <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> սարքի ձեր կարգավորումներում։</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Հավելվածի պատկերակ"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"«Այլ տեղեկություններ» կոճակ"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string> + <string name="permission_notification" msgid="693762568127741203">"Ծանուցումներ"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Կարող է կարդալ բոլոր ծանուցումները, ներառյալ տեղեկությունները, օրինակ՝ կոնտակտները, հաղորդագրությունները և լուսանկարները"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml index 82fa00aa45b4..ef35e49071d4 100644 --- a/packages/CompanionDeviceManager/res/values-in/strings.xml +++ b/packages/CompanionDeviceManager/res/values-in/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string> <string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk dikelola oleh <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Aplikasi ini diperlukan untuk mengelola <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan diizinkan berinteraksi dengan notifikasi dan mengakses izin Telepon, SMS, Kontak, Kalender, Log panggilan, dan Perangkat di sekitar."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikasi"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikasi ponsel"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses informasi ini dari ponsel Anda"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses informasi ini dari ponsel Anda"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifikasi"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Dapat membaca semua notifikasi, termasuk informasi seperti kontak, pesan, dan foto"</string> - <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string> <string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Ini termasuk akses Mikrofon, Kamera, dan Lokasi, serta izin sensitif lainnya di <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Anda dapat mengubah izin ini kapan saja di Setelan pada <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikon Aplikasi"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Tombol Informasi Lainnya"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifikasi"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Dapat membaca semua notifikasi, termasuk informasi seperti kontak, pesan, dan foto"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml index 59f4f8971881..9ca64a5099a1 100644 --- a/packages/CompanionDeviceManager/res/values-is/strings.xml +++ b/packages/CompanionDeviceManager/res/values-is/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"úr"</string> <string name="chooser_title" msgid="2262294130493605839">"Velja <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sem <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> á að stjórna"</string> - <string name="summary_watch" msgid="3002344206574997652">"Þetta forrit er nauðsynlegt til að hafa umsjón með <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær aðgang að tilkynningum og heimildum síma, SMS, tengiliða, dagatals, símtalaskráa og nálægra tækja."</string> - <string name="permission_apps" msgid="6142133265286656158">"Forrit"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Streymdu forritum símans"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að þessum upplýsingum úr símanum þínum"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um heimild til straumspilunar forrita á milli tækjanna þinna fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að þessum upplýsingum úr símanum þínum"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Tilkynningar"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Getur lesið allar tilkynningar, þar á meðal upplýsingar á borð við tengiliði, skilaboð og myndir"</string> - <string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um aðgang að myndum, margmiðlunarefni og tilkynningum símans þíns fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> <string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Þetta kann að fela í sér aðgang að hljóðnema, myndavél og staðsetningu og aðrar heimildir fyrir viðkvæmu efni í <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Hægt er að breyta þessum heimildum hvenær sem er í stillingunum í <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Tákn forrits"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Hnappur fyrir upplýsingar"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string> + <string name="permission_notification" msgid="693762568127741203">"Tilkynningar"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Getur lesið allar tilkynningar, þar á meðal upplýsingar á borð við tengiliði, skilaboð og myndir"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml index 793f0b89a34a..67ed6b877a25 100644 --- a/packages/CompanionDeviceManager/res/values-it/strings.xml +++ b/packages/CompanionDeviceManager/res/values-it/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Consenti all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"orologio"</string> <string name="chooser_title" msgid="2262294130493605839">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> da gestire con <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Questa app è necessaria per gestire il tuo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. L\'app <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le tue notifiche e accedere alle autorizzazioni Telefono, SMS, Contatti, Calendar, Registri chiamate e Dispositivi nelle vicinanze."</string> - <string name="permission_apps" msgid="6142133265286656158">"App"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Trasmetti in streaming le app del tuo telefono"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Consenti a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a queste informazioni dal tuo telefono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Consenti a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a questa informazione dal tuo telefono"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notifiche"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Puoi leggere tutte le notifiche, incluse le informazioni come contatti, messaggi e foto"</string> - <string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche del telefono"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Potrebbero essere incluse le autorizzazioni di accesso al microfono, alla fotocamera e alla posizione, nonché altre autorizzazioni sensibili su <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Puoi cambiare queste autorizzazioni in qualsiasi momento nelle Impostazioni su <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Icona dell\'app"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Pulsante Altre informazioni"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string> + <string name="permission_notification" msgid="693762568127741203">"Notifiche"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Puoi leggere tutte le notifiche, incluse le informazioni come contatti, messaggi e foto"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml index b4141253a163..8689fea51f42 100644 --- a/packages/CompanionDeviceManager/res/values-iw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong&g; לגשת אל <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"שעון"</string> <string name="chooser_title" msgid="2262294130493605839">"בחירת <xliff:g id="PROFILE_NAME">%1$s</xliff:g> לניהול באמצעות <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לבצע פעולות בהתראות ותקבל הרשאות גישה לטלפון, ל-SMS לאנשי הקשר, ליומן, ליומני השיחות ולמכשירים בקרבת מקום."</string> - <string name="permission_apps" msgid="6142133265286656158">"אפליקציות"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"שידור אפליקציות מהטלפון"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"התראות"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"גישת קריאה לכל ההתראות, כולל מידע כמו אנשי קשר, הודעות ותמונות."</string> - <string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string> <string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>ההרשאות עשויות לכלול גישה למיקרופון, למצלמה ולמיקום, וכן גישה למידע רגיש אחר ב-</strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p&gt; <p>אפשר לשנות את ההרשאות האלה בכל שלב בהגדרות של <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"סמל האפליקציה"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"לחצן מידע נוסף"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string> + <string name="permission_notification" msgid="693762568127741203">"התראות"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"גישת קריאה לכל ההתראות, כולל מידע כמו אנשי קשר, הודעות ותמונות."</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml index a3cd4ee3df28..f6321b5fa908 100644 --- a/packages/CompanionDeviceManager/res/values-ja/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> へのアクセスを許可"</string> <string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string> - <string name="summary_watch" msgid="3002344206574997652">"このアプリは<xliff:g id="DEVICE_NAME">%1$s</xliff:g>の管理に必要です。<xliff:g id="APP_NAME">%2$s</xliff:g> は、通知の使用と、電話、SMS、連絡先、カレンダー、通話履歴、付近のデバイスの権限へのアクセスが可能となります。"</string> - <string name="permission_apps" msgid="6142133265286656158">"アプリ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"スマートフォンのアプリをストリーミングします"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"スマートフォンのこの情報へのアクセスを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"通知"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"連絡先、メッセージ、写真に関する情報を含め、すべての通知を読み取ることができます"</string> - <string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってスマートフォンの写真、メディア、通知にアクセスする権限をリクエストしています"</string> <string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>これには、<strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> のマイク、カメラ、位置情報へのアクセスや、その他の機密情報に関わる権限が含まれる可能性があります。</p> <p>これらの権限は <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> の [設定] でいつでも変更できます。</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"アプリのアイコン"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"詳細情報ボタン"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string> + <string name="permission_notification" msgid="693762568127741203">"通知"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"連絡先、メッセージ、写真に関する情報を含め、すべての通知を読み取ることができます"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml index dbb1760d39bf..e31ff8a9e6d7 100644 --- a/packages/CompanionDeviceManager/res/values-ka/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"დაუშვით <strong><xliff:g id="APP_NAME">%1$s</xliff:g>-ის</strong>, წვდომა თქვენს <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ზე</strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"საათი"</string> <string name="chooser_title" msgid="2262294130493605839">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, რომელიც უნდა მართოს <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>-მა"</string> - <string name="summary_watch" msgid="3002344206574997652">"ეს აპი საჭიროა თქვენი <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ს სამართავად. <xliff:g id="APP_NAME">%2$s</xliff:g> შეძლებს თქვენს შეტყობინებებთან ინტერაქციას და თქვენი ტელეფონის, SMS-ების, კონტაქტებისა, კალენდრის, ზარების ჟურნალისა და ახლომახლო მოწყობილობების ნებართვებზე წვდომას."</string> - <string name="permission_apps" msgid="6142133265286656158">"აპები"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"თქვენი ტელეფონის აპების სტრიმინგი"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის აპების სტრიმინგი შეძლოს"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ნება დართეთ, რომ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"შეტყობინებები"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"შეუძლია წაიკითხოს ყველა შეტყობინება, მათ შორის ისეთი ინფორმაცია, როგორიცაა კონტაქტები, ტექსტური შეტყობინებები და ფოტოები"</string> - <string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ წვდომა ჰქონდეს თქვენი ტელეფონის ფოტოებზე, მედიასა და შეტყობინებებზე"</string> <string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>აღნიშნული შეიძლება მოიცავდეს მიკროფონზე, კამერასა და მდებარეობაზე წვდომას თუ სხვა ნებართვას სენსიტიურ ინფორმაციაზე <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>-ში.</p> <p>ამ ნებართვების შეცვლა ნებისმიერ დროს შეგიძლიათ თქვენი პარამეტრებიდან <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>-ში.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"აპის ხატულა"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"დამატებითი ინფორმაციის ღილაკი"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string> + <string name="permission_notification" msgid="693762568127741203">"შეტყობინებები"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"შეუძლია წაიკითხოს ყველა შეტყობინება, მათ შორის ისეთი ინფორმაცია, როგორიცაა კონტაქტები, ტექსტური შეტყობინებები და ფოტოები"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml index 0d92a97b640e..f82a1d517942 100644 --- a/packages/CompanionDeviceManager/res/values-kk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> құрылғысын пайдалануға рұқсат беру"</string> <string name="profile_name_watch" msgid="576290739483672360">"сағат"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> арқылы басқарылатын <xliff:g id="PROFILE_NAME">%1$s</xliff:g> құрылғысын таңдаңыз"</string> - <string name="summary_watch" msgid="3002344206574997652">"Бұл қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысын басқару үшін қажет. <xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына хабарландырулар жіберу, Телефон, SMS, Контактілер, Күнтізбе, Қоңырау журналдары қолданбаларын және маңайдағы құрылғыларды пайдалану рұқсаттары беріледі."</string> - <string name="permission_apps" msgid="6142133265286656158">"Қолданбалар"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Телефон қолданбаларын трансляциялайды."</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Хабарландырулар"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Барлық хабарландыруды, соның ішінде контактілер, хабарлар және фотосуреттер сияқты ақпаратты оқи алады."</string> - <string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан телефондағы фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалану үшін рұқсат сұрайды."</string> <string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Оларға микрофонды, камераны және геодеректі пайдалану рұқсаттары, сондай-ақ <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> құрылғысына берілетін басқа да құпия ақпарат рұқсаттары кіруі мүмкін.</p> <p>Бұл рұқсаттарды кез келген уақытта <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> құрылғысындағы параметрлерден өзгерте аласыз.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Қолданба белгішесі"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"\"Қосымша ақпарат\" түймесі"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string> + <string name="permission_notification" msgid="693762568127741203">"Хабарландырулар"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Барлық хабарландыруды, соның ішінде контактілер, хабарлар және фотосуреттер сияқты ақпаратты оқи алады."</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml index 4d85cfd9c3e7..07a195a46237 100644 --- a/packages/CompanionDeviceManager/res/values-km/strings.xml +++ b/packages/CompanionDeviceManager/res/values-km/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលប្រើប្រាស់ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> របស់អ្នក"</string> <string name="profile_name_watch" msgid="576290739483672360">"នាឡិកា"</string> <string name="chooser_title" msgid="2262294130493605839">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីឱ្យស្ថិតក្រោមការគ្រប់គ្រងរបស់ <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក។ <xliff:g id="APP_NAME">%2$s</xliff:g> នឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើអន្តរកម្មជាមួយការជូនដំណឹងរបស់អ្នក និងចូលប្រើការអនុញ្ញាតទូរសព្ទ, SMS, ទំនាក់ទំនង, ប្រតិទិន, កំណត់ហេតុហៅទូរសព្ទ និងឧបករណ៍នៅជិតរបស់អ្នក។"</string> - <string name="permission_apps" msgid="6142133265286656158">"កម្មវិធី"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"ផ្សាយកម្មវិធីរបស់ទូរសព្ទអ្នក"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលមើលព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"ការជូនដំណឹង"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"អាចអានការជូនដំណឹងទាំងអស់ រួមទាំងព័ត៌មានដូចជាទំនាក់ទំនង សារ និងរូបថត"</string> - <string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ទូរសព្ទអ្នក"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>សកម្មភាពនេះអាចរួមបញ្ចូលការចូលប្រើទីតាំង កាមេរ៉ា និងមីក្រូហ្វូន និងការអនុញ្ញាតដែលមានលក្ខណៈរសើបផ្សេងទៀតនៅលើ <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>។</p> <p>អ្នកអាចប្ដូរការអនុញ្ញាតទាំងនេះបានគ្រប់ពេលវេលានៅក្នុងការកំណត់នៅលើ <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>។</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"រូបកម្មវិធី"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"ប៊ូតុងព័ត៌មានបន្ថែម"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string> + <string name="permission_notification" msgid="693762568127741203">"ការជូនដំណឹង"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"អាចអានការជូនដំណឹងទាំងអស់ រួមទាំងព័ត៌មានដូចជាទំនាក់ទំនង សារ និងរូបថត"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml index a8a790a92eaf..b453f3b0be67 100644 --- a/packages/CompanionDeviceManager/res/values-kn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"ನಿಮ್ಮ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ಅನ್ನು ಪ್ರವೇಶಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string> <string name="profile_name_watch" msgid="576290739483672360">"ವೀಕ್ಷಿಸಿ"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> - <string name="summary_watch" msgid="3002344206574997652">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. ಅನ್ನು ನಿರ್ವಹಿಸಲು ಈ ಆ್ಯಪ್ನ ಅಗತ್ಯವಿದೆ. ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು ಮತ್ತು ನಿಮ್ಮ ಫೋನ್, SMS, ಸಂಪರ್ಕಗಳು, Calendar, ಕರೆಯ ಲಾಗ್ಗಳು ಹಾಗೂ ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ಅನುಮತಿಗಳನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ."</string> - <string name="permission_apps" msgid="6142133265286656158">"ಆ್ಯಪ್ಗಳು"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"ನಿಮ್ಮ ಫೋನ್ನ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"ಅಧಿಸೂಚನೆಗಳು"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"ಸಂಪರ್ಕಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಫೋಟೋಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ಓದಬಹುದು"</string> - <string name="permission_storage" msgid="6831099350839392343">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ಸೇವೆಗಳು"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"ನಿಮ್ಮ ಫೋನ್ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>ಇದು <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> ನಲ್ಲಿನ ಮೈಕ್ರೊಫೋನ್, ಕ್ಯಾಮರಾ ಮತ್ತು ಸ್ಥಳ ಆ್ಯಕ್ಸೆಸ್ ಹಾಗೂ ಇತರ ಸೂಕ್ಷ್ಮ ಅನುಮತಿಗಳನ್ನು ಹೊಂದಿರಬಹುದು<p></p> <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> ನಲ್ಲಿನ ನಿಮ್ಮ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ನೀವು ಈ ಅನುಮತಿಗಳನ್ನು ಯಾವಾಗ ಬೇಕಾದರೂ ಬದಲಾಯಿಸಬಹುದು.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ಆ್ಯಪ್ ಐಕಾನ್"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"ಹೆಚ್ಚಿನ ಮಾಹಿತಿಯ ಬಟನ್"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮ"</string> + <string name="permission_notification" msgid="693762568127741203">"ಅಧಿಸೂಚನೆಗಳು"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"ಸಂಪರ್ಕಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಫೋಟೋಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ಓದಬಹುದು"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml index c78affa83764..361d3b2f5e7c 100644 --- a/packages/CompanionDeviceManager/res/values-ko/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 내 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> 기기에 액세스하도록 허용"</string> <string name="profile_name_watch" msgid="576290739483672360">"시계"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>을(를) 선택"</string> - <string name="summary_watch" msgid="3002344206574997652">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 프로필을 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 알림과 상호작용하고 내 전화, SMS, 연락처, Calendar, 통화 기록, 근처 기기에 대한 권한을 갖게 됩니다."</string> - <string name="permission_apps" msgid="6142133265286656158">"앱"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"휴대전화의 앱을 스트리밍합니다."</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>이 휴대전화의 이 정보에 액세스하도록 허용합니다."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 앱이 휴대전화에서 이 정보에 액세스하도록 허용"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"알림"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"연락처, 메시지, 사진 등의 정보를 포함한 모든 알림을 읽을 수 있습니다."</string> - <string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 휴대전화의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다."</string> <string name="profile_name_generic" msgid="6851028682723034988">"기기"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>여기에는 <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>에서 허용했던 마이크, 카메라, 위치 정보 액세스 권한 및 기타 민감한 권한이 포함될 수 있습니다.</p> <p>언제든지 <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>의 설정에서 이러한 권한을 변경할 수 있습니다.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"앱 아이콘"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"추가 정보 버튼"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string> + <string name="permission_notification" msgid="693762568127741203">"알림"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"연락처, 메시지, 사진 등의 정보를 포함한 모든 알림을 읽을 수 있습니다."</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml index ead203721afe..57b2747d44a3 100644 --- a/packages/CompanionDeviceManager/res/values-ky/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> түзмөгүңүзгө кирүүгө уруксат бериңиз"</string> <string name="profile_name_watch" msgid="576290739483672360">"саат"</string> <string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> тарабынан башкарылсын"</string> - <string name="summary_watch" msgid="3002344206574997652">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздү башкаруу үчүн керек. <xliff:g id="APP_NAME">%2$s</xliff:g> билдирмелериңизди көрүп, телефонуңуз, SMS билдирүүлөр, байланыштар, жылнаама, чалуулар тизмеси жана жакын жердеги түзмөктөргө болгон уруксаттарды пайдалана алат."</string> - <string name="permission_apps" msgid="6142133265286656158">"Колдонмолор"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Телефондогу колдонмолорду алып ойнотуу"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду өткөрүүгө уруксат сурап жатат"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Билдирмелер"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Бардык билдирмелерди, анын ичинде байланыштар, билдирүүлөр жана сүрөттөр сыяктуу маалыматты окуй алат"</string> - <string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиафайлдар"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string> <string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Бул уруксаттарга микрофонго, камерага жана жайгашкан жерге кирүү мүмкүнчүлүгү жана <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> түзмөгүндөгү башка купуя маалыматты көрүүгө уруксаттар кириши мүмкүн.</p> <p>Бул уруксаттарды каалаган убакта <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> түзмөгүндөгү Жөндөөлөрдөн өзгөртө аласыз.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Колдонмонун сүрөтчөсү"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Дагы маалымат баскычы"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиафайлдар"</string> + <string name="permission_notification" msgid="693762568127741203">"Билдирмелер"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Бардык билдирмелерди, анын ичинде байланыштар, билдирүүлөр жана сүрөттөр сыяктуу маалыматты окуй алат"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml index 6a9197e84933..9ec713638750 100644 --- a/packages/CompanionDeviceManager/res/values-lo/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ຂອງທ່ານໄດ້"</string> <string name="profile_name_watch" msgid="576290739483672360">"ໂມງ"</string> <string name="chooser_title" msgid="2262294130493605839">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ເພື່ອໃຫ້ຖືກຈັດການໂດຍ <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"ຕ້ອງໃຊ້ແອັບນີ້ເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ. <xliff:g id="APP_NAME">%2$s</xliff:g> ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ໂຕ້ຕອບກັບການແຈ້ງເຕືອນຂອງທ່ານ ແລະ ເຂົ້າເຖິງການອະນຸຍາດໂທລະສັບ, SMS, ລາຍຊື່ຜູ້ຕິດຕໍ່, ປະຕິທິນ, ບັນທຶກການໂທ ແລະ ອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງຂອງທ່ານ."</string> - <string name="permission_apps" msgid="6142133265286656158">"ແອັບ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"ສະຕຣີມແອັບຂອງໂທລະສັບທ່ານ"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"ການແຈ້ງເຕືອນ"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"ສາມາດອ່ານການແຈ້ງເຕືອນທັງໝົດ, ຮວມທັງຂໍ້ມູນ ເຊັ່ນ: ລາຍຊື່ຜູ້ຕິດຕໍ່, ຂໍ້ຄວາມ ແລະ ຮູບພາບ"</string> - <string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອເຂົ້າເຖິງຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຂອງໂທລະສັບທ່ານ"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>ນີ້ອາດຮວມສິດເຂົ້າເຖິງໄມໂຄຣໂຟນ, ກ້ອງຖ່າຍຮູບ ແລະ ສະຖານທີ່, ຮວມທັງການອະນຸຍາດທີ່ລະອຽດອ່ອນອື່ນໆຢູ່ <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>ທ່ານສາມາດປ່ຽນການອະນຸຍາດເຫຼົ່ານີ້ຕອນໃດກໍໄດ້ໃນການຕັ້ງຄ່າຂອງທ່ານຢູ່ <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ໄອຄອນແອັບ"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"ປຸ່ມຂໍ້ມູນເພີ່ມເຕີມ"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string> + <string name="permission_notification" msgid="693762568127741203">"ການແຈ້ງເຕືອນ"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"ສາມາດອ່ານການແຈ້ງເຕືອນທັງໝົດ, ຮວມທັງຂໍ້ມູນ ເຊັ່ນ: ລາຍຊື່ຜູ້ຕິດຕໍ່, ຂໍ້ຄວາມ ແລະ ຮູບພາບ"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml index f2cbfa0adb11..664059527e48 100644 --- a/packages/CompanionDeviceManager/res/values-lt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti jūsų <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"laikrodį"</string> <string name="chooser_title" msgid="2262294130493605839">"Jūsų <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, kurį valdys <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> (pasirinkite)"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ši programa reikalinga norint tvarkyti jūsų „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su pranešimų funkcija ir pasiekti telefono, SMS, Kontaktų, Kalendoriaus, Skambučių žurnalų ir įrenginių netoliese leidimus."</string> - <string name="permission_apps" msgid="6142133265286656158">"Programos"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Telefono programų perdavimas srautu"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti šią informaciją iš jūsų telefono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti šią informaciją iš jūsų telefono"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Pranešimai"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Galima skaityti visus pranešimus, įskaitant tokią informaciją kaip kontaktai, pranešimai ir nuotraukos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų pasiekti telefono nuotraukas, mediją ir pranešimus"</string> <string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Gali būti įtraukti prieigos prie mikrofono, kameros ir vietovės leidimai ir kiti leidimai pasiekti neskelbtiną informaciją <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> įrenginyje.</p> <p>Šiuos leidimus galite bet kada pakeisti „Nustatymų“ skiltyje <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> įrenginyje.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Programos piktograma"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Mygtukas „Daugiau informacijos“"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string> + <string name="permission_notification" msgid="693762568127741203">"Pranešimai"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Galima skaityti visus pranešimus, įskaitant tokią informaciją kaip kontaktai, pranešimai ir nuotraukos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml index e8947c7eea44..ae246363c0ba 100644 --- a/packages/CompanionDeviceManager/res/values-lv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Atļauja lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt jūsu ierīcei <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"pulkstenis"</string> <string name="chooser_title" msgid="2262294130493605839">"Profila (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) izvēle, ko pārvaldīt lietotnē <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Šī lietotne ir nepieciešama jūsu ierīces (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) pārvaldībai. Lietotnei <xliff:g id="APP_NAME">%2$s</xliff:g> tiks atļauts mijiedarboties ar jūsu paziņojumiem un piekļūt šādām atļaujām: Tālrunis, Īsziņas, Kontaktpersonas, Kalendārs, Zvanu žurnāli un Tuvumā esošas ierīces."</string> - <string name="permission_apps" msgid="6142133265286656158">"Lietotnes"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Var straumēt jūsu tālruņa lietotnes"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt šai informācijai no jūsu tālruņa"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt šai informācijai no jūsu tālruņa"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Paziņojumi"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Var lasīt visus paziņojumus, tostarp tādu informāciju kā kontaktpersonas, ziņojumi un fotoattēli."</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju piekļūt jūsu tālruņa fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Tās var būt mikrofona, kameras, atrašanās vietas piekļuves atļaujas un citas sensitīvas atļaujas ierīcē <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Atļaujas jebkurā brīdī varat mainīt ierīces <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p> iestatījumos."</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Lietotnes ikona"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Plašākas informācijas poga"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string> + <string name="permission_notification" msgid="693762568127741203">"Paziņojumi"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Var lasīt visus paziņojumus, tostarp tādu informāciju kā kontaktpersonas, ziņojumi un fotoattēli."</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml index 6ef9e5d9066e..cdecb20c6115 100644 --- a/packages/CompanionDeviceManager/res/values-mk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Дозволете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до вашиот <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string> <string name="chooser_title" msgid="2262294130493605839">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> со којшто ќе управува <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Апликацијава е потребна за управување со вашиот <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ќе може да остварува интеракција со известувањата и да пристапува до дозволите за телефонот, SMS, контактите, календарот, евиденцијата на повици и уредите во близина."</string> - <string name="permission_apps" msgid="6142133265286656158">"Апликации"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Стримувајте ги апликациите на телефонот"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Овозможете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до овие податоци на телефонот"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Дозволете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до овие податоци на телефонот"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Известувања"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"може да ги чита сите известувања, вклучително и податоци како контакти, пораки и фотографии"</string> - <string name="permission_storage" msgid="6831099350839392343">"Аудиовизуелни содржини"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string> <string name="profile_name_generic" msgid="6851028682723034988">"уред"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Ова може да вклучува пристап до микрофон, камера и локација и други чувствителни дозволи на <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Може да ги промените дозволиве во секое време во вашите „Поставки“ на <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Икона на апликацијата"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Копче за повеќе информации"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Аудиовизуелни содржини"</string> + <string name="permission_notification" msgid="693762568127741203">"Известувања"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"може да ги чита сите известувања, вклучително и податоци како контакти, пораки и фотографии"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml index 07e6a43a407d..15434fc596b7 100644 --- a/packages/CompanionDeviceManager/res/values-ml/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"നിങ്ങളുടെ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> എന്നതിനെ അനുവദിക്കുക"</string> <string name="profile_name_watch" msgid="576290739483672360">"വാച്ച്"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string> - <string name="summary_watch" msgid="3002344206574997652">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ഈ ആപ്പ് ആവശ്യമാണ്. നിങ്ങളുടെ അറിയിപ്പുകളുമായി ആശയവിനിമയം നടത്താനും നിങ്ങളുടെ ഫോൺ, SMS, കോൺടാക്റ്റുകൾ, കലണ്ടർ, കോൾ ചരിത്രം, സമീപമുള്ള ഉപകരണങ്ങളുടെ അനുമതികൾ എന്നിവ ആക്സസ് ചെയ്യാനും <xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിനെ അനുവദിക്കും."</string> - <string name="permission_apps" msgid="6142133265286656158">"ആപ്പുകൾ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"നിങ്ങളുടെ ഫോണിലെ ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ആപ്പിനെ അനുവദിക്കുക"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ആപ്പിനെ അനുവദിക്കുക"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"അറിയിപ്പുകൾ"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"കോൺടാക്റ്റുകൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ മുതലായ വിവരങ്ങൾ ഉൾപ്പെടെയുള്ള എല്ലാ അറിയിപ്പുകളും വായിക്കാനാകും"</string> - <string name="permission_storage" msgid="6831099350839392343">"ഫോട്ടോകളും മീഡിയയും"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play സേവനങ്ങൾ"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p><strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> എന്നതിലെ മൈക്രോഫോൺ, ക്യാമറ, ലൊക്കേഷൻ ആക്സസ്, സെൻസിറ്റീവ് വിവരങ്ങൾക്കുള്ള മറ്റ് അനുമതികൾ എന്നിവയും ഇതിൽ ഉൾപ്പെട്ടേക്കാം<p>നിങ്ങൾക്ക് <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p> എന്നതിലെ ക്രമീകരണത്തിൽ ഏതുസമയത്തും ഈ അനുമതികൾ മാറ്റാം."</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ആപ്പ് ഐക്കൺ"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"കൂടുതൽ വിവരങ്ങൾ ബട്ടൺ"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ഫോട്ടോകളും മീഡിയയും"</string> + <string name="permission_notification" msgid="693762568127741203">"അറിയിപ്പുകൾ"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"കോൺടാക്റ്റുകൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ മുതലായ വിവരങ്ങൾ ഉൾപ്പെടെയുള്ള എല്ലാ അറിയിപ്പുകളും വായിക്കാനാകും"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml index 1c74e48488f2..8361bd8009e1 100644 --- a/packages/CompanionDeviceManager/res/values-mn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-д таны <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д хандахыг зөвшөөрнө үү"</string> <string name="profile_name_watch" msgid="576290739483672360">"цаг"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>-н удирдах<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г сонгоно уу"</string> - <string name="summary_watch" msgid="3002344206574997652">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-г удирдахад шаардлагатай. <xliff:g id="APP_NAME">%2$s</xliff:g>-д таны мэдэгдэлтэй харилцан үйлдэл хийж, Утас, SMS, Харилцагчид, Календарь, Дуудлагын жагсаалт болон Ойролцоох төхөөрөмжүүдийн зөвшөөрөлд хандахыг зөвшөөрнө."</string> - <string name="permission_apps" msgid="6142133265286656158">"Аппууд"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Таны утасны аппуудыг дамжуулах"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Мэдэгдэл"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Харилцагчид, мессеж болон зураг зэрэг мэдээллийг оруулаад бүх мэдэгдлийг унших боломжтой"</string> - <string name="permission_storage" msgid="6831099350839392343">"Зураг болон медиа"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play үйлчилгээ"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Таны утасны зураг, медиа болон мэдэгдэлд хандахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string> <string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Үүнд Микрофон, Камер болон Байршлын хандалт болон <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> дээрх бусад эмзэг зөвшөөрөл багтаж болно.</p> <p>Та эдгээр зөвшөөрлийг <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> дээрх Тохиргоо хэсэгтээ хүссэн үедээ өөрчлөх боломжтой.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Aппын дүрс тэмдэг"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Дэлгэрэнгүй мэдээллийн товчлуур"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Зураг болон медиа"</string> + <string name="permission_notification" msgid="693762568127741203">"Мэдэгдэл"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Харилцагчид, мессеж болон зураг зэрэг мэдээллийг оруулаад бүх мэдэгдлийг унших боломжтой"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml index 1cc0412998de..65be3671f8d1 100644 --- a/packages/CompanionDeviceManager/res/values-mr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"तुमचे <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> अॅक्सेस करण्यासाठी <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला अनुमती द्या"</string> <string name="profile_name_watch" msgid="576290739483672360">"वॉच"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> द्वारे व्यवस्थापित करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string> - <string name="summary_watch" msgid="3002344206574997652">"तुमची <xliff:g id="DEVICE_NAME">%1$s</xliff:g> प्रोफाइल व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="APP_NAME">%2$s</xliff:g> ला तुमच्या सूचनांशी संवाद साधण्याची आणि तुमचा फोन, एसएमएस, संपर्क कॅलेंडर, कॉल लॉग व जवळपासच्या डिव्हाइसच्या परवानग्या अॅक्सेस करण्याची अनुमती मिळेल."</string> - <string name="permission_apps" msgid="6142133265286656158">"ॲप्स"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"फोनवरील ॲप्स स्ट्रीम करा"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला ही माहिती तुमच्या फोनवरून अॅक्सेस करण्यासाठी अनुमती द्या"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला ही माहिती तुमच्या फोनवरून अॅक्सेस करण्यासाठी अनुमती द्या"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"सूचना"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"संपर्क, मेसेज आणि फोटो यांसारख्या माहितीचा समावेश असलेल्या सर्व सूचना वाचू शकते"</string> - <string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string> <string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>यामध्ये <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g><strong> वरील मायक्रोफोन, कॅमेरा आणि स्थान अॅक्सेस व इतर संवेदनशील परवानग्यांचा समावेश असू शकतो </strong>.</p> <p>तुम्ही <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> वर तुमच्या सेटिंग्ज मध्ये या परवानग्या कधीही बदलू शकता</strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"अॅप आयकन"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"अधिक माहिती बटण"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string> + <string name="permission_notification" msgid="693762568127741203">"सूचना"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"संपर्क, मेसेज आणि फोटो यांसारख्या माहितीचा समावेश असलेल्या सर्व सूचना वाचू शकते"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml index 02743f00783d..a2a8e2ad21a5 100644 --- a/packages/CompanionDeviceManager/res/values-ms/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> anda"</string> <string name="profile_name_watch" msgid="576290739483672360">"jam tangan"</string> <string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk diurus oleh <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan berinteraksi dengan pemberitahuan anda dan mengakses kebenaran Telefon, SMS, Kenalan, Kalendar, Log panggilan dan Peranti berdekatan anda."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apl"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Strim apl telefon anda"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses maklumat ini daripada telefon anda"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses maklumat ini daripada telefon anda"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Pemberitahuan"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Boleh membaca semua pemberitahuan, termasuk maklumat seperti kenalan, mesej dan foto"</string> - <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Perkhidmatan Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk mengakses foto, media dan pemberitahuan telefon anda"</string> <string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Ini mungkin termasuk akses Mikrofon, Kamera dan Lokasi serta kebenaran sensitif lain pada <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Anda boleh menukar kebenaran ini pada bila-bila masa dalam Tetapan anda pada <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikon Apl"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Butang Maklumat Lagi"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string> + <string name="permission_notification" msgid="693762568127741203">"Pemberitahuan"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Boleh membaca semua pemberitahuan, termasuk maklumat seperti kenalan, mesej dan foto"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml index 61272cc720c9..87dc08a427a9 100644 --- a/packages/CompanionDeviceManager/res/values-my/strings.xml +++ b/packages/CompanionDeviceManager/res/values-my/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"သင်၏ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ကို သုံးရန် <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ကို ခွင့်ပြုပါ"</string> <string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> က စီမံခန့်ခွဲရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးချယ်ပါ"</string> - <string name="summary_watch" msgid="3002344206574997652">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်ကိုလိုအပ်သည်။ သင်၏ ‘ဖုန်း’၊ ‘SMS စာတိုစနစ်’၊ ‘အဆက်အသွယ်များ’၊ ‘ပြက္ခဒိန်’၊ ‘ခေါ်ဆိုမှတ်တမ်း’ နှင့် \'အနီးတစ်ဝိုက်ရှိ စက်များ\' ခွင့်ပြုချက်များကို သုံးရန်နှင့် အကြောင်းကြားချက်များကို ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> အား ခွင့်ပြုပါမည်။"</string> - <string name="permission_apps" msgid="6142133265286656158">"အက်ပ်များ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်လွှင့်နိုင်သည်"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အား သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုခြင်း"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"အကြောင်းကြားချက်များ"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"အဆက်အသွယ်၊ မက်ဆေ့ဂျ်နှင့် ဓာတ်ပုံကဲ့သို့ အချက်အလက်များအပါအဝင် အကြောင်းကြားချက်အားလုံးကို ဖတ်နိုင်သည်"</string> - <string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string> <string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>၎င်းတွင် မိုက်ခရိုဖုန်း၊ ကင်မရာ၊ တည်နေရာ အသုံးပြုခွင့်အပြင် <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>ပေါ်ရှိ အခြား သတိထားရမည့် ခွင့်ပြုချက်များ ပါဝင်နိုင်သည်။</p> <p>ဤခွင့်ပြုချက်များကို <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>ပေါ်ရှိ သင်၏ဆက်တင်များတွင် အချိန်မရွေးပြောင်းနိုင်သည်။</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"အက်ပ်သင်္ကေတ"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"နောက်ထပ်အချက်အလက်များ ခလုတ်"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string> + <string name="permission_notification" msgid="693762568127741203">"အကြောင်းကြားချက်များ"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"အဆက်အသွယ်၊ မက်ဆေ့ဂျ်နှင့် ဓာတ်ပုံကဲ့သို့ အချက်အလက်များအပါအဝင် အကြောင်းကြားချက်အားလုံးကို ဖတ်နိုင်သည်"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml index 6df06c13c155..82a0282219ab 100644 --- a/packages/CompanionDeviceManager/res/values-nb/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Tillat at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> bruker <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"klokke"</string> <string name="chooser_title" msgid="2262294130493605839">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal administreres av <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Denne appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillatelse til å samhandle med varslene dine og får tilgang til tillatelser for telefon, SMS, kontakter, kalender, samtalelogger og enheter i nærheten."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apper"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Strøm appene på telefonen"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å strømme apper mellom enhetene dine, på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Varsler"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kan lese alle varsler, inkludert informasjon som kontakter, meldinger og bilder"</string> - <string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å få tilgang til bilder, medier og varsler på telefonen din, på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Dette kan inkludere tilgang til mikrofon, kamera og posisjon samt andre sensitive tillatelser på <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Du kan når som helst endre disse tillatelsene i innstillingene på <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Appikon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Mer informasjon-knapp"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string> + <string name="permission_notification" msgid="693762568127741203">"Varsler"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kan lese alle varsler, inkludert informasjon som kontakter, meldinger og bilder"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml index fc225088b916..d7d3459703db 100644 --- a/packages/CompanionDeviceManager/res/values-ne/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"आफ्नो <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> लाई <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> प्रयोग गर्ने अनुमति दिनुहोस्"</string> <string name="profile_name_watch" msgid="576290739483672360">"घडी"</string> <string name="chooser_title" msgid="2262294130493605839">"आफूले <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> प्रयोग गरी व्यवस्थापन गर्न चाहेको <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चयन गर्नुहोस्"</string> - <string name="summary_watch" msgid="3002344206574997652">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एपलाई अनुमति दिनु पर्ने हुन्छ। <xliff:g id="APP_NAME">%2$s</xliff:g> लाई तपाईंका सूचना हेर्ने र फोन, SMS, कन्ट्याक्ट, पात्रो, कल लग तथा नजिकैका डिभाइससम्बन्धी अनुमतिहरू हेर्ने तथा प्रयोग गर्ने अनुमति दिइने छ।"</string> - <string name="permission_apps" msgid="6142133265286656158">"एपहरू"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"आफ्नो फोनका एपहरू प्रयोग गर्नुहोस्"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"सूचनाहरू"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"कन्ट्याक्ट, म्यासेज र फोटोलगायतका जानकारीसहित सबै सूचनाहरू पढ्न सक्छ"</string> - <string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंको फोनमा भएका फोटो, मिडिया र सूचनाहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ"</string> <string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>यसअन्तर्गत <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> का माइक्रोफोन, क्यामेरा र लोकेसन प्रयोग गर्ने अनुमतिका तथा अन्य संवेदनशील अनुमति समावेश हुन्छन्।</p> <p>तपाईं <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> का सेटिङमा गई जुनसुकै बेला यी अनुमति परिवर्तन गर्न सक्नुहुन्छ।</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"एपको आइकन"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"थप जानकारी देखाउने बटन"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string> + <string name="permission_notification" msgid="693762568127741203">"सूचनाहरू"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"कन्ट्याक्ट, म्यासेज र फोटोलगायतका जानकारीसहित सबै सूचनाहरू पढ्न सक्छ"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml index 9c7cc3c988b7..ed8890b96f38 100644 --- a/packages/CompanionDeviceManager/res/values-nl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot je <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"horloge"</string> <string name="chooser_title" msgid="2262294130493605839">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om te beheren met <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Deze app is vereist om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> kan interactie hebben met je meldingen en toegang krijgen tot rechten voor Telefoon, Sms, Contacten, Agenda, Gesprekslijsten en Apparaten in de buurt."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Stream de apps van je telefoon"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot deze informatie op je telefoon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot deze informatie op je telefoon"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Meldingen"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kan alle meldingen lezen, waaronder informatie zoals contacten, berichten en foto\'s"</string> - <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string> <string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Dit kan toegang tot de microfoon, camera en je locatie en andere gevoelige rechten op je <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> omvatten.</p> <p>Je kunt deze rechten op elk moment wijzigen in je Instellingen op de <xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"App-icoon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Knop Meer informatie"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string> + <string name="permission_notification" msgid="693762568127741203">"Meldingen"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kan alle meldingen lezen, waaronder informatie zoals contacten, berichten en foto\'s"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml index e56780607c71..225074c97450 100644 --- a/packages/CompanionDeviceManager/res/values-or/strings.xml +++ b/packages/CompanionDeviceManager/res/values-or/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"ଆପଣଙ୍କ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>କୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string> <string name="profile_name_watch" msgid="576290739483672360">"ୱାଚ୍"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>କୁ ବାଛନ୍ତୁ"</string> - <string name="summary_watch" msgid="3002344206574997652">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଏହି ଆପ ଆବଶ୍ୟକ। ଆପଣଙ୍କ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରିବା ଏବଂ ଆପଣଙ୍କ ଫୋନ, SMS, ଯୋଗାଯୋଗ, କ୍ୟାଲେଣ୍ଡର, କଲ ଲଗ ଏବଂ ଆଖପାଖର ଡିଭାଇସ ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ।"</string> - <string name="permission_apps" msgid="6142133265286656158">"ଆପ୍ସ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"ଆପଣଙ୍କ ଫୋନର ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"ଯୋଗାଯୋଗ, ମେସେଜ ଏବଂ ଫଟୋଗୁଡ଼ିକ ପରି ସୂଚନା ସମେତ ସମସ୍ତ ବିଜ୍ଞପ୍ତିକୁ ପଢ଼ିପାରିବ"</string> - <string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>ଏହା <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>ରେ ମାଇକ୍ରୋଫୋନ, କ୍ୟାମେରା ଏବଂ ଲୋକେସନ ଆକ୍ସେସ ଓ ଅନ୍ୟ ସମ୍ବେଦନଶୀଳ ଅନୁମତିଗୁଡ଼ିକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରିପାରେ।</p> <p>ଆପଣ <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>ରେ ଯେ କୌଣସି ସମୟରେ ଆପଣଙ୍କ ସେଟିଂସରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ପରିବର୍ତ୍ତନ କରିପାରିବେ।</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ଆପ ଆଇକନ"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"ଅଧିକ ସୂଚନା ବଟନ"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string> + <string name="permission_notification" msgid="693762568127741203">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"ଯୋଗାଯୋଗ, ମେସେଜ ଏବଂ ଫଟୋଗୁଡ଼ିକ ପରି ସୂଚନା ସମେତ ସମସ୍ତ ବିଜ୍ଞପ୍ତିକୁ ପଢ଼ିପାରିବ"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml index dba72eb9260e..00fbc3c7c380 100644 --- a/packages/CompanionDeviceManager/res/values-pa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string> <string name="profile_name_watch" msgid="576290739483672360">"ਸਮਾਰਟ-ਵਾਚ"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string> - <string name="summary_watch" msgid="3002344206574997652">"ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਇਹ ਐਪ ਲੋੜੀਂਦੀ ਹੈ। <xliff:g id="APP_NAME">%2$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀਆਂ ਸੂਚਨਾਵਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰਨ ਅਤੇ ਤੁਹਾਡੇ ਫ਼ੋਨ, SMS, ਸੰਪਰਕਾਂ, ਕੈਲੰਡਰ, ਕਾਲ ਲੌਗਾਂ ਅਤੇ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਸੰਬੰਧੀ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ।"</string> - <string name="permission_apps" msgid="6142133265286656158">"ਐਪਾਂ"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"ਸੂਚਨਾਵਾਂ"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"ਤੁਸੀਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਪੜ੍ਹ ਸਕਦੇ ਹੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਸੰਪਰਕਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਫ਼ੋਟੋਆਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੁੰਦੀ ਹੈ"</string> - <string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>ਇਸ ਵਿੱਚ ਮਾਈਕ੍ਰੋਫ਼ੋਨ, ਕੈਮਰਾ, ਟਿਕਾਣਾ ਪਹੁੰਚ ਅਤੇ <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> \'ਤੇ ਮੌਜੂਦ ਹੋਰ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਸੰਬੰਧੀ ਇਜਾਜ਼ਤਾਂ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀਆਂ ਹਨ।</p> <p>ਤੁਸੀਂ <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> \'ਤੇ ਮੌਜੂਦ ਆਪਣੀਆਂ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਕਦੇ ਵੀ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਬਦਲ ਸਕਦੇ ਹੋ।</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ਐਪ ਪ੍ਰਤੀਕ"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"ਹੋਰ ਜਾਣਕਾਰੀ ਬਟਨ"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string> + <string name="permission_notification" msgid="693762568127741203">"ਸੂਚਨਾਵਾਂ"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"ਤੁਸੀਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਪੜ੍ਹ ਸਕਦੇ ਹੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਸੰਪਰਕਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਫ਼ੋਟੋਆਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੁੰਦੀ ਹੈ"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml index a6320269f650..f312507ae659 100644 --- a/packages/CompanionDeviceManager/res/values-pl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Zezwól na dostęp aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> do urządzenia <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"zegarek"</string> <string name="chooser_title" msgid="2262294130493605839">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, którym ma zarządzać aplikacja <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ta aplikacja jest niezbędna do zarządzania profilem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacja <xliff:g id="APP_NAME">%2$s</xliff:g> będzie mogła korzystać z powiadomień oraz uprawnień dotyczących telefonu, SMS-ów, kontaktów, kalendarza, rejestrów połączeń i urządzeń w pobliżu."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikacje"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Odtwarzaj strumieniowo aplikacje z telefonu"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Zezwól urządzeniu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania treści z aplikacji na innym urządzeniu"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Powiadomienia"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Może odczytywać wszystkie powiadomienia, w tym informacje takie jak kontakty, wiadomości i zdjęcia"</string> - <string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na telefonie"</string> <string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Mogą one obejmować dane dostęp do Mikrofonu, Aparatu i lokalizacji oraz inne uprawnienia newralgiczne na urządzeniu <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Możesz w dowolnym momencie zmienić uprawnienia na urządzeniu <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacji"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Przycisk – więcej informacji"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string> + <string name="permission_notification" msgid="693762568127741203">"Powiadomienia"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Może odczytywać wszystkie powiadomienia, w tym informacje takie jak kontakty, wiadomości i zdjęcia"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml index 60a407966c79..d1b8774149e8 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string> <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Esse app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. O <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com suas notificações e acessar os apps Telefone, SMS, Contatos, Google Agenda, registros de chamadas e as permissões de dispositivos por perto."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Fazer transmissão dos apps no seu smartphone"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificações"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Isso pode incluir acesso a microfone, câmera e localização e outras permissões sensíveis no <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Você pode mudar essas permissões a qualquer momento nas configurações do <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ícone do app"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Botão \"Mais informações\""</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificações"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml index 8eabaf8a6dcf..a11f7ff22b52 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda ao seu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string> <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerido pela app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Esta app é necessária para gerir o seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com as suas notificações e aceder às autorizações do Telefone, SMS, Contactos, Calendário, Registos de chamadas e Dispositivos próximos."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Faça stream das apps do telemóvel"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda a estas informações do seu telemóvel"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permita que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda a estas informações do seu telemóvel"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificações"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contactos, mensagens e fotos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos e multimédia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Isto pode incluir o acesso ao microfone, câmara e localização, bem como a outras autorizações confidenciais no dispositivo <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Pode alterar estas autorizações em qualquer altura nas Definições do dispositivo <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ícone da app"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Botão Mais informações"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos e multimédia"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificações"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contactos, mensagens e fotos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml index 60a407966c79..d1b8774149e8 100644 --- a/packages/CompanionDeviceManager/res/values-pt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string> <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Esse app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. O <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com suas notificações e acessar os apps Telefone, SMS, Contatos, Google Agenda, registros de chamadas e as permissões de dispositivos por perto."</string> - <string name="permission_apps" msgid="6142133265286656158">"Apps"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Fazer transmissão dos apps no seu smartphone"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificações"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Isso pode incluir acesso a microfone, câmera e localização e outras permissões sensíveis no <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Você pode mudar essas permissões a qualquer momento nas configurações do <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ícone do app"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Botão \"Mais informações\""</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificações"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml index d1f949d7fc77..7c33ab3d61fd 100644 --- a/packages/CompanionDeviceManager/res/values-ro/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Permite ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze dispozitivul <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"ceas"</string> <string name="chooser_title" msgid="2262294130493605839">"Alege un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Această aplicație este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să interacționeze cu notificările și să acceseze permisiunile pentru Telefon, SMS, Agendă, Calendar, Jurnale de apeluri și Dispozitive din apropiere."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplicații"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Să redea în stream aplicațiile telefonului"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Permite ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze aceste informații de pe telefon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele tale"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permite ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze aceste informații de pe telefon"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Notificări"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Poate să citească toate notificările, inclusiv informații cum ar fi agenda, mesajele și fotografiile"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotografii și media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servicii Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Aici pot fi incluse accesul la microfon, la camera foto, la locație și alte permisiuni de accesare a informațiilor sensibile de pe <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Poți modifica oricând aceste permisiuni din Setările de pe <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Pictograma aplicației"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Butonul Mai multe informații"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotografii și media"</string> + <string name="permission_notification" msgid="693762568127741203">"Notificări"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Poate să citească toate notificările, inclusiv informații cum ar fi agenda, mesajele și fotografiile"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml index f519239234d5..d82fa76a2c4b 100644 --- a/packages/CompanionDeviceManager/res/values-ru/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ к устройству <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"часы"</string> <string name="chooser_title" msgid="2262294130493605839">"Выберите устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), которым будет управлять приложение <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" получит доступ к уведомлениям, а также следующие разрешения: телефон, SMS, контакты, календарь, список вызовов и устройства поблизости."</string> - <string name="permission_apps" msgid="6142133265286656158">"Приложения"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Трансляция приложений с телефона."</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы транслировать приложения между вашими устройствами."</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Уведомления"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Чтение всех уведомлений, в том числе сведений о контактах, сообщениях и фотографиях."</string> - <string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string> <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Сюда может входить доступ к микрофону, камере и данным о местоположении, а также другие разрешения на доступ к конфиденциальной информации на устройстве <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Вы можете в любое время изменить разрешения в настройках устройства <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Значок приложения"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Кнопка информации"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string> + <string name="permission_notification" msgid="693762568127741203">"Уведомления"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Чтение всех уведомлений, в том числе сведений о контактах, сообщениях и фотографиях."</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml index bf5361ea6bfa..f58f042380a9 100644 --- a/packages/CompanionDeviceManager/res/values-si/strings.xml +++ b/packages/CompanionDeviceManager/res/values-si/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> කළමනාකරණය කිරීමට ඉඩ දෙන්න"</string> <string name="profile_name_watch" msgid="576290739483672360">"ඔරලෝසුව"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> මගින් කළමනාකරණය කරනු ලැබීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string> - <string name="summary_watch" msgid="3002344206574997652">"මෙම යෙදුමට ඔබගේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> කළමනාකරණය කිරීමට අවශ්යයි. <xliff:g id="APP_NAME">%2$s</xliff:g> ඔබගේ දැනුම්දීම් සමඟ අන්තර්ක්රියා කිරීමට සහ ඔබගේ දුරකථනය, SMS, සම්බන්ධතා, දින දර්ශනය, ඇමතුම් ලොග සහ අවට උපාංග අවසර වෙත ප්රවේශ වීමට ඉඩ දෙනු ඇත."</string> - <string name="permission_apps" msgid="6142133265286656158">"යෙදුම්"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"ඔබගේ දුරකථනයේ යෙදුම් ප්රවාහ කරන්න"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්රවේශ වීමට ඉඩ දෙන්න"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්රවේශ වීමට ඉඩ දෙන්න"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"දැනුම්දීම්"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"සම්බන්ධතා, පණිවිඩ සහ ඡායාරූප වැනි තොරතුරු ඇතුළුව සියලු දැනුම්දීම් කියවිය හැකිය"</string> - <string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්ය"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්ය සහ දැනුම්දීම් වෙත ප්රවේශ වීමට අවසරය ඉල්ලමින් සිටියි"</string> <string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>මෙයට මයික්රෆෝනය, කැමරාව සහ ස්ථාන ප්රවේශය සහ <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> හි අනෙකුත් සංවේදී අවසර ඇතුළත් විය හැකිය.</p> <p>ඔබට ඔබගේ සැකසීම් තුළ <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> හිදී ඕනෑම වේලාවක මෙම අවසර වෙනස් කළ හැකිය.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"යෙදුම් නිරූපකය"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"වැඩිදුර තොරතුරු බොත්තම"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්ය"</string> + <string name="permission_notification" msgid="693762568127741203">"දැනුම්දීම්"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"සම්බන්ධතා, පණිවිඩ සහ ඡායාරූප වැනි තොරතුරු ඇතුළුව සියලු දැනුම්දීම් කියවිය හැකිය"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml index ff19fa577448..492a235de004 100644 --- a/packages/CompanionDeviceManager/res/values-sk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k zariadeniu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string> <string name="chooser_title" msgid="2262294130493605839">"Vyberte profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý bude spravovať aplikácia <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Táto aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s vašimi upozorneniami a získa prístup k povoleniam telefónu, SMS, kontaktov, kalendára, zoznamu hovorov a zariadení v okolí."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikácie"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Streamovať aplikácie telefónu"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Upozornenia"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Môže čítať všetky upozornenia vrátane informácií, ako sú kontakty, správy a fotky"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string> <string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Môžu zahŕňať prístup k mikrofónu, kamere a polohe a ďalšie citlivé povolenia v zariadení <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Tieto povolenia môžete kedykoľvek zmeniť v Nastaveniach v zariadení <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikácie"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Tlačidlo Ďalšie informácie"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string> + <string name="permission_notification" msgid="693762568127741203">"Upozornenia"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Môže čítať všetky upozornenia vrátane informácií, ako sú kontakty, správy a fotky"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml index 14feef6fee19..09ebcdfa9111 100644 --- a/packages/CompanionDeviceManager/res/values-sl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovolite dostop do naprave <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"ura"</string> <string name="chooser_title" msgid="2262294130493605839">"Izbira naprave <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ki jo bo upravljala aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bosta omogočena interakcija z obvestili in uporaba dovoljenj Telefon, SMS, Stiki, Koledar, Dnevniki klicev in Naprave v bližini."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Pretočno predvajanje aplikacij telefona"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Obvestila"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Lahko bere vsa obvestila, vključno s podatki, kot so stiki, sporočila in fotografije."</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v telefonu."</string> <string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>To lahko vključuje dostop do mikrofona, fotoaparata in lokacije ter druga občutljiva dovoljenja v napravi <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Ta dovoljenja lahko kadar koli spremenite v nastavitvah v napravi <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Gumb za več informacij"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string> + <string name="permission_notification" msgid="693762568127741203">"Obvestila"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Lahko bere vsa obvestila, vključno s podatki, kot so stiki, sporočila in fotografije."</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml index cefbff8e1ffb..3879cb318ef1 100644 --- a/packages/CompanionDeviceManager/res/values-sq/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje te <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string> <string name="chooser_title" msgid="2262294130493605839">"Zgjidh një profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> që do të menaxhohet nga <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ky aplikacion nevojitet për të menaxhuar profilin tënd të <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Kalendarit\", \"Evidencave të telefonatave\" dhe \"Pajisjeve në afërsi\"."</string> - <string name="permission_apps" msgid="6142133265286656158">"Aplikacionet"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Transmeto aplikacionet e telefonit tënd"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Njoftimet"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Mund të lexojë të gjitha njoftimet, duke përfshirë informacione si kontaktet, mesazhet dhe fotografitë"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string> <string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Kjo mund të përfshijë qasjen te \"Mikrofoni\", \"Kamera\", \"Vendndodhja\" dhe leje të tjera për informacione delikate në <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p&gtTi mund t\'i ndryshosh këto leje në çdo kohë te \"Cilësimet\" në <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona e aplikacionit"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Butoni \"Më shumë informacione\""</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string> + <string name="permission_notification" msgid="693762568127741203">"Njoftimet"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Mund të lexojë të gjitha njoftimet, duke përfshirë informacione si kontaktet, mesazhet dhe fotografitë"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml index 0d05e1ac1b76..6ad111f77431 100644 --- a/packages/CompanionDeviceManager/res/values-sr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа уређају <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"сат"</string> <string name="chooser_title" msgid="2262294130493605839">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Ова апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за интеракцију са обавештењима и приступ дозволама за телефон, SMS, контакте, календар, евиденције позива и уређаје у близини."</string> - <string name="permission_apps" msgid="6142133265286656158">"Апликације"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Обавештења"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Може да чита сва обавештења, укључујући информације попут контаката, порука и слика"</string> - <string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string> <string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>То може да обухвата приступ микрофону, камери и локацији, као и другим осетљивим дозволама на уређају <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>У сваком тренутку можете да промените те дозволе у Подешавањима на уређају <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Икона апликације"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Дугме за више информација"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string> + <string name="permission_notification" msgid="693762568127741203">"Обавештења"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Може да чита сва обавештења, укључујући информације попут контаката, порука и слика"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml index e2799b5aeeff..cd5d8de57c77 100644 --- a/packages/CompanionDeviceManager/res/values-sv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Tillåt att <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> får åtkomst till din <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"klocka"</string> <string name="chooser_title" msgid="2262294130493605839">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för hantering av <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillåtelse att interagera med dina aviseringar och får åtkomst till behörigheterna Telefon, Sms, Kontakter, Kalender, Samtalsloggar och Enheter i närheten."</string> - <string name="permission_apps" msgid="6142133265286656158">"Appar"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Streama telefonens appar"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Ge <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> åtkomstbehörighet till denna information på telefonen"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> streama appar mellan enheter"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Ge <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> åtkomstbehörighet till denna information på telefonen"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Aviseringar"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kan läsa alla aviseringar, inklusive information som kontakter, meddelanden och foton"</string> - <string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att ge <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> åtkomst till foton, mediefiler och aviseringar på telefonen"</string> <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Det kan gälla behörighet till mikrofon, kamera och plats och åtkomstbehörighet till andra känsliga uppgifter på <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Du kan när som helst ändra behörigheterna i inställningarna på <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.lt;/p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Appikon"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Knappen Mer information"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string> + <string name="permission_notification" msgid="693762568127741203">"Aviseringar"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kan läsa alla aviseringar, inklusive information som kontakter, meddelanden och foton"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml index 812b4df347b8..a1c354f9f394 100644 --- a/packages/CompanionDeviceManager/res/values-sw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> yako"</string> <string name="profile_name_watch" msgid="576290739483672360">"saa"</string> <string name="chooser_title" msgid="2262294130493605839">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili idhibitiwe na <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Programu hii inahitajika ili udhibiti wasifu wako wa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kufikia arifa zako na kufikia ruhusa zako za Simu, SMS, Anwani, Kalenda, Rekodi za nambari za simu na Vifaa vilivyo karibu."</string> - <string name="permission_apps" msgid="6142133265286656158">"Programu"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Tiririsha programu za simu yako"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie maelezo haya kutoka kwenye simu yako"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili itiririshe programu kati ya vifaa vyako"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie maelezo haya kutoka kwenye simu yako"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Arifa"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Inaweza kusoma arifa zote, ikiwa ni pamoja na maelezo kama vile anwani, ujumbe na picha"</string> - <string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili ifikie picha, maudhui na arifa za simu yako"</string> <string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Hii huenda ikajumuisha ufikiaji wa Maikrofoni, Kamera na Mahali, pamoja na ruhusa nyingine nyeti kwenye <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Unaweza kubadilisha ruhusa hizi muda wowote katika Mipangilio yako kwenye <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Aikoni ya Programu"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Kitufe cha Maelezo Zaidi"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string> + <string name="permission_notification" msgid="693762568127741203">"Arifa"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Inaweza kusoma arifa zote, ikiwa ni pamoja na maelezo kama vile anwani, ujumbe na picha"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml index fca9e0a23040..e75b75ee27df 100644 --- a/packages/CompanionDeviceManager/res/values-ta/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"உங்கள் <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> சாதனத்தை அணுக <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதியுங்கள்"</string> <string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேர்ந்தெடுங்கள்"</string> - <string name="summary_watch" msgid="3002344206574997652">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவைப்படுகிறது. உங்கள் அறிவிப்புகளைப் பயன்படுத்துவதற்கான அனுமதியையும் மொபைல், மெசேஜ், தொடர்புகள், கேலெண்டர், அழைப்புப் பதிவுகள், அருகிலுள்ள சாதனங்கள் ஆகியவற்றின் அனுமதிகளுக்கான அணுகலையும் <xliff:g id="APP_NAME">%2$s</xliff:g> ஆப்ஸ் பெறும்."</string> - <string name="permission_apps" msgid="6142133265286656158">"ஆப்ஸ்"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"உங்கள் மொபைலின் ஆப்ஸை ஸ்ட்ரீம் செய்யலாம்"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவும்"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"உங்கள் மொபைலிலிருந்து இந்தத் தகவலை அணுக <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதியுங்கள்"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"அறிவிப்புகள்"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"தொடர்புகள், மெசேஜ்கள், படங்கள் போன்ற தகவல்கள் உட்பட அனைத்து அறிவிப்புகளையும் படிக்க முடியும்"</string> - <string name="permission_storage" msgid="6831099350839392343">"படங்கள் மற்றும் மீடியா"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string> <string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p><strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p> சாதனத்தில் உள்ள மைக்ரோஃபோன், கேமரா, இருப்பிட அணுகல், பாதுகாக்கவேண்டிய பிற தகவல்கள் ஆகியவற்றுக்கான அனுமதிகள் இதிலடங்கும்.<strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p> சாதனத்தில் உள்ள அமைப்புகளில் இந்த அனுமதிகளை எப்போது வேண்டுமானாலும் நீங்கள் மாற்றிக்கொள்ளலாம்."</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ஆப்ஸ் ஐகான்"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"கூடுதல் தகவல்கள் பட்டன்"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"படங்கள் மற்றும் மீடியா"</string> + <string name="permission_notification" msgid="693762568127741203">"அறிவிப்புகள்"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"தொடர்புகள், மெசேஜ்கள், படங்கள் போன்ற தகவல்கள் உட்பட அனைத்து அறிவிப்புகளையும் படிக்க முடியும்"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml index c3187963086b..b44b59c1e505 100644 --- a/packages/CompanionDeviceManager/res/values-te/strings.xml +++ b/packages/CompanionDeviceManager/res/values-te/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"మీ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ను యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను అనుమతించండి"</string> <string name="profile_name_watch" msgid="576290739483672360">"వాచ్"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ద్వారా మేనేజ్ చేయబడటానికి ఒక <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను ఎంచుకోండి"</string> - <string name="summary_watch" msgid="3002344206574997652">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. మీ నోటిఫికేషన్లతో ఇంటరాక్ట్ అవ్వడానికి అలాగే మీ ఫోన్, SMS, కాంటాక్ట్లు, Calendar కాల్ లాగ్లు, సమీపంలోని పరికరాల అనుమతులను యాక్సెస్ చేయడానికి <xliff:g id="APP_NAME">%2$s</xliff:g> అనుమతించబడుతుంది."</string> - <string name="permission_apps" msgid="6142133265286656158">"యాప్లు"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"మీ ఫోన్ యాప్లను స్ట్రీమ్ చేయండి"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"మీ పరికరాల మధ్య యాప్లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"నోటిఫికేషన్లు"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"కాంటాక్ట్లు, మెసేజ్లు, ఫోటోల వంటి సమాచారంతో సహా అన్ని నోటిఫికేషన్లను చదవగలదు"</string> - <string name="permission_storage" msgid="6831099350839392343">"ఫోటోలు, మీడియా"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play సర్వీసులు"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> మీ ఫోన్లోని ఫోటోలను, మీడియాను, ఇంకా నోటిఫికేషన్లను యాక్సెస్ చేయడానికి మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string> <string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p><strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>లో మైక్రోఫోన్, కెమెరా, లొకేషన్ యాక్సెస్, ఇంకా ఇతర గోప్యమైన సమాచార యాక్సెస్ అనుమతులు ఇందులో ఉండవచ్చు.</p> <p>మీరు <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>లో మీ సెట్టింగ్లలో ఎప్పుడైనా ఈ అనుమతులను మార్చవచ్చు.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"యాప్ చిహ్నం"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"మరింత సమాచారం బటన్"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"ఫోటోలు, మీడియా"</string> + <string name="permission_notification" msgid="693762568127741203">"నోటిఫికేషన్లు"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"కాంటాక్ట్లు, మెసేజ్లు, ఫోటోల వంటి సమాచారంతో సహా అన్ని నోటిఫికేషన్లను చదవగలదు"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml index 7c31a21aef60..237d129496bc 100644 --- a/packages/CompanionDeviceManager/res/values-th/strings.xml +++ b/packages/CompanionDeviceManager/res/values-th/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึง <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ของคุณ"</string> <string name="profile_name_watch" msgid="576290739483672360">"นาฬิกา"</string> <string name="chooser_title" msgid="2262294130493605839">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะให้มีการจัดการโดย <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g> จะได้รับอนุญาตให้โต้ตอบกับการแจ้งเตือนและได้รับสิทธิ์เข้าถึงโทรศัพท์, SMS, รายชื่อติดต่อ, ปฏิทิน, บันทึกการโทร และอุปกรณ์ที่อยู่ใกล้เคียง"</string> - <string name="permission_apps" msgid="6142133265286656158">"แอป"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"สตรีมแอปของโทรศัพท์คุณ"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"การแจ้งเตือน"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"สามารถอ่านการแจ้งเตือนทั้งหมด รวมถึงข้อมูลอย่างรายชื่อติดต่อ ข้อความ และรูปภาพ"</string> - <string name="permission_storage" msgid="6831099350839392343">"รูปภาพและสื่อ"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"บริการ Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อเข้าถึงรูปภาพ สื่อ และการแจ้งเตือนในโทรศัพท์ของคุณ"</string> <string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>โดยอาจรวมถึงสิทธิ์เข้าถึงไมโครโฟน กล้อง และตำแหน่ง ตลอดจนสิทธิ์ที่มีความละเอียดอ่อนอื่นๆ ใน <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>คุณเปลี่ยนแปลงสิทธิ์เหล่านี้ได้ทุกเมื่อในการตั้งค่าใน <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ไอคอนแอป"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"ปุ่มข้อมูลเพิ่มเติม"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"รูปภาพและสื่อ"</string> + <string name="permission_notification" msgid="693762568127741203">"การแจ้งเตือน"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"สามารถอ่านการแจ้งเตือนทั้งหมด รวมถึงข้อมูลอย่างรายชื่อติดต่อ ข้อความ และรูปภาพ"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml index e86bc41432a4..86e6898012bd 100644 --- a/packages/CompanionDeviceManager/res/values-tl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang iyong <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"relo"</string> <string name="chooser_title" msgid="2262294130493605839">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para pamahalaan ng <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Kailangan ang app na ito para mapamahalaan ang iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na makipag-ugnayan sa mga notification mo at i-access ang iyong pahintulot sa Telepono, SMS, Mga Contact, Kalendaryo, Log ng mga tawag, at Mga kalapit na device."</string> - <string name="permission_apps" msgid="6142133265286656158">"Mga App"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"I-stream ang mga app ng iyong telepono"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang impormasyong ito sa iyong telepono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang impormasyon sa iyong telepono"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Mga Notification"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Magbasa ng lahat ng notification, kabilang ang impormasyon gaya ng mga contact, mensahe, at larawan"</string> - <string name="permission_storage" msgid="6831099350839392343">"Mga larawan at media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Mga serbisyo ng Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Posibleng kabilang dito ang access sa Mikropono, Camera, at Lokasyon, at iba pang pahintulot sa sensitibong impormasyon sa <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Puwede mong baguhin ang mga pahintulot na ito anumang oras sa iyong Mga Setting sa <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Icon ng App"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Button ng Dagdag Impormasyon"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Mga larawan at media"</string> + <string name="permission_notification" msgid="693762568127741203">"Mga Notification"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Magbasa ng lahat ng notification, kabilang ang impormasyon gaya ng mga contact, mensahe, at larawan"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml index 756bcbbf855a..2cb03f765e6a 100644 --- a/packages/CompanionDeviceManager/res/values-tr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazınıza erişmesi için <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasına izin verin"</string> <string name="profile_name_watch" msgid="576290739483672360">"saat"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> tarafından yönetilecek bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string> - <string name="summary_watch" msgid="3002344206574997652">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızın yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> adlı uygulamanın bildirimlerinizle etkileşimde bulunup Telefon, SMS, Kişiler, Takvim, Arama kayıtları ve Yakındaki cihazlar izinlerinize erişmesine izin verilir."</string> - <string name="permission_apps" msgid="6142133265286656158">"Uygulamalar"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun uygulamalarını yayınlama"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Bildirimler"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Kişiler, mesajlar ve fotoğraflar da dahil olmak üzere tüm bildirimleri okuyabilir"</string> - <string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string> <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Mikrofon, Kamera ve Konum erişiminin yanı sıra <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> cihazındaki diğer hassas bilgilere erişim izinleri de bu kapsamda olabilir.</p> <p>Bu izinleri istediğiniz zaman <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> cihazındaki Ayarlar bölümünden değiştirebilirsiniz.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Uygulama Simgesi"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Daha Fazla Bilgi Düğmesi"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string> + <string name="permission_notification" msgid="693762568127741203">"Bildirimler"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Kişiler, mesajlar ve fotoğraflar da dahil olmak üzere tüm bildirimleri okuyabilir"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml index cc9f6b508208..905c62a7fb38 100644 --- a/packages/CompanionDeviceManager/res/values-uk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Надати додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до пристрою <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"годинник"</string> <string name="chooser_title" msgid="2262294130493605839">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, яким керуватиме додаток <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"Цей додаток потрібен, щоб керувати пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Додаток <xliff:g id="APP_NAME">%2$s</xliff:g> зможе взаємодіяти з вашими сповіщеннями й отримає дозволи \"Телефон\", \"SMS\", \"Контакти\", \"Календар\", \"Журнали викликів\" і \"Пристрої поблизу\"."</string> - <string name="permission_apps" msgid="6142133265286656158">"Додатки"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Транслювати додатки телефона"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до цієї інформації з телефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на трансляцію додатків між вашими пристроями"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Надайте пристрою <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до цієї інформації з телефона"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Сповіщення"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Може читати всі сповіщення, зокрема таку інформацію, як контакти, повідомлення та фотографії"</string> - <string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень вашого телефона"</string> <string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Це може бути доступ до мікрофона, камери та геоданих, а також до іншої конфіденційної інформації на пристрої <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Ви можете будь-коли змінити ці дозволи в налаштуваннях на пристрої <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Значок додатка"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Кнопка \"Докладніше\""</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string> + <string name="permission_notification" msgid="693762568127741203">"Сповіщення"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Може читати всі сповіщення, зокрема таку інформацію, як контакти, повідомлення та фотографії"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml index 65b2ba576d41..ed1453ccc4d1 100644 --- a/packages/CompanionDeviceManager/res/values-ur/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو اپنے <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> تک رسائی کی اجازت دیں"</string> <string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> کے ذریعے نظم کئے جانے کیلئے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو منتخب کریں"</string> - <string name="summary_watch" msgid="3002344206574997652">"آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کا نظم کرنے کے لئے اس ایپ کی ضرورت ہے۔ <xliff:g id="APP_NAME">%2$s</xliff:g> کو آپ کی اطلاعات کے ساتھ تعامل کرنے اور آپ کے فون، SMS، رابطوں، کیلنڈر، کال لاگز اور قریبی آلات کی اجازتوں تک رسائی کی اجازت ہوگی۔"</string> - <string name="permission_apps" msgid="6142133265286656158">"ایپس"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"اپنے فون کی ایپس کی سلسلہ بندی کریں"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو اجازت دیں"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"اپنے فون سے اس معلومات تک رسائی حاصل کرنے کی <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو اجازت دیں"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"اطلاعات"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"رابطوں، پیغامات اور تصاویر جیسی معلومات سمیت تمام اطلاعات پڑھ سکتے ہیں"</string> - <string name="permission_storage" msgid="6831099350839392343">"تصاویر اور میڈیا"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play سروسز"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے فون کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت طلب کر رہی ہے"</string> <string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>اس میں مائیکروفون، کیمرا اور مقام تک رسائی اور ;<strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong&gt پر دیگر حساس اجازتیں شامل ہو سکتی ہیں۔</p> <p>آپ <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>;</strong&gt پر کسی بھی وقت اپنی ترتیبات میں ان اجازتوں کو تبدیل کر سکتے ہیں۔</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"ایپ کا آئیکن"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"مزید معلومات کا بٹن"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"تصاویر اور میڈیا"</string> + <string name="permission_notification" msgid="693762568127741203">"اطلاعات"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"رابطوں، پیغامات اور تصاویر جیسی معلومات سمیت تمام اطلاعات پڑھ سکتے ہیں"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml index befb37050927..bc945095d70a 100644 --- a/packages/CompanionDeviceManager/res/values-uz/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> qurilmasiga kirish uchun <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga ruxsat bering"</string> <string name="profile_name_watch" msgid="576290739483672360">"soat"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> boshqaradigan <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qurilmasini tanlang"</string> - <string name="summary_watch" msgid="3002344206574997652">"Bu ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> profilini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga bildirishnomalar bilan ishlash va telefon, SMS, kontaktlar, taqvim, chaqiruvlar jurnali va yaqin-atrofdagi qurilmalarga kirishga ruxsat beriladi."</string> - <string name="permission_apps" msgid="6142133265286656158">"Ilovalar"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Telefondagi ilovalarni translatsiya qilish"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Bildirishnomalar"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Barcha bildirishnomalarni, jumladan, kontaktlar, xabarlar va suratlarni oʻqishi mumkin"</string> - <string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"Telefoningizdagi rasm, media va bildirishnomalarga kirish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string> <string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Bunga <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong> qurilmasidagi Mikrofon, Kamera, Joylashuv kabi muhim ruxsatlar kirishi mumkin.</p> <p>Bu ruxsatlarni istalgan vaqt <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong> Sozlamalari orqali oʻzgartirish mumkin.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Ilova belgisi"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Batafsil axborot tugmasi"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string> + <string name="permission_notification" msgid="693762568127741203">"Bildirishnomalar"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Barcha bildirishnomalarni, jumladan, kontaktlar, xabarlar va suratlarni oʻqishi mumkin"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml index b29e08c8d382..c5dd928fa84c 100644 --- a/packages/CompanionDeviceManager/res/values-vi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> của bạn"</string> <string name="profile_name_watch" msgid="576290739483672360">"đồng hồ"</string> <string name="chooser_title" msgid="2262294130493605839">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sẽ do <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> quản lý"</string> - <string name="summary_watch" msgid="3002344206574997652">"Cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="APP_NAME">%2$s</xliff:g> sẽ được phép tương tác với các thông báo và truy cập vào Điện thoại, SMS, Danh bạ, Lịch, Nhật ký cuộc gọi và quyền đối với Thiết bị ở gần."</string> - <string name="permission_apps" msgid="6142133265286656158">"Ứng dụng"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Truyền các ứng dụng trên điện thoại của bạn"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào thông tin này trên điện thoại của bạn"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào thông tin này trên điện thoại của bạn"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Thông báo"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Có thể đọc tất cả các thông báo, kể cả những thông tin như danh bạ, tin nhắn và ảnh"</string> - <string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string> <string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Những quyền này có thể bao gồm quyền truy cập vào micrô, máy ảnh và thông tin vị trí, cũng như các quyền truy cập thông tin nhạy cảm khác trên <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Bạn có thể thay đổi những quyền này bất cứ lúc nào trong phần Cài đặt trên <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Biểu tượng ứng dụng"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Nút thông tin khác"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string> + <string name="permission_notification" msgid="693762568127741203">"Thông báo"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Có thể đọc tất cả các thông báo, kể cả những thông tin như danh bạ, tin nhắn và ảnh"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml index 7b3be4451d06..b08e8f4717ef 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"允许<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>访问您的<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"手表"</string> <string name="chooser_title" msgid="2262294130493605839">"选择要由<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> - <string name="summary_watch" msgid="3002344206574997652">"需要使用此应用,才能管理您的“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”。“<xliff:g id="APP_NAME">%2$s</xliff:g>”将能与通知互动,并可获得电话、短信、通讯录、日历、通话记录和附近的设备访问权限。"</string> - <string name="permission_apps" msgid="6142133265286656158">"应用"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"流式传输手机上的应用"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”<strong></strong>访问您手机中的这项信息"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 访问您手机中的这项信息"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"通知"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"可以读取所有通知,包括合同、消息和照片等信息"</string> - <string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string> <string name="profile_name_generic" msgid="6851028682723034988">"设备"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>这可能包括<strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>的麦克风、摄像头和位置信息访问权限,以及其他敏感权限。</p> <p>您可以随时在<strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>的“设置”中更改这些权限。</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"应用图标"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"更多信息按钮"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string> + <string name="permission_notification" msgid="693762568127741203">"通知"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"可以读取所有通知,包括合同、消息和照片等信息"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml index ede2369a3270..94ebb3d65c19 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"允許<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 存取您的 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string> <string name="chooser_title" msgid="2262294130493605839">"選擇由 <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> 管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> - <string name="summary_watch" msgid="3002344206574997652">"必須使用此應用程式,才能管理<xliff:g id="DEVICE_NAME">%1$s</xliff:g>。<xliff:g id="APP_NAME">%2$s</xliff:g> 將可存取通知、電話、短訊、通訊錄和日曆、通話記錄和附近的裝置權限。"</string> - <string name="permission_apps" msgid="6142133265286656158">"應用程式"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"串流播放手機應用程式內容"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取您手機中的這項資料"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在為 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求權限,以在裝置之間串流應用程式內容"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取您手機中的這項資料"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"通知"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"可以讀取所有通知,包括聯絡人、訊息和電話等資訊"</string> - <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求權限,以便存取手機上的相片、媒體和通知"</string> <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>這可能包括 <strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p> 的麥克風、相機和位置存取權和其他敏感資料權限。您隨時可透過 <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p> 變更這些權限。"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"應用程式圖示"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"「更多資料」按鈕"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string> + <string name="permission_notification" msgid="693762568127741203">"通知"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"可以讀取所有通知,包括聯絡人、訊息和電話等資訊"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml index 675072b1dfd2..adf8708f53f0 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>"</string> <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string> <string name="chooser_title" msgid="2262294130493605839">"選擇要讓「<xliff:g id="APP_NAME">%2$s</xliff:g>」<strong></strong>管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> - <string name="summary_watch" msgid="3002344206574997652">"你必須使用這個應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可存取通知、電話、簡訊、聯絡人和日曆、通話記錄和鄰近裝置的權限。"</string> - <string name="permission_apps" msgid="6142133265286656158">"應用程式"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"串流傳輸手機應用程式內容"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取手機中的這項資訊"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便在裝置之間串流傳輸應用程式內容"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取你手機中的這項資訊"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"通知"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"可讀取所有通知,包括聯絡人、訊息和電話等資訊"</string> - <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便存取手機上的相片、媒體和通知"</string> <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>這可能包括「<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>」<strong></strong>.</p>的麥克風、相機和位置資訊存取權和其他機密權限。</p> <p>你隨時可透過「<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>」<strong></strong>的設定變更這些權限。</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"應用程式圖示"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"更多資訊按鈕"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string> + <string name="permission_notification" msgid="693762568127741203">"通知"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"可讀取所有通知,包括聯絡人、訊息和電話等資訊"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml index ec87f2dc2f27..c4e634c5ad0c 100644 --- a/packages/CompanionDeviceManager/res/values-zu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml @@ -20,9 +20,10 @@ <string name="confirmation_title" msgid="3785000297483688997">"Vumela i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukuthi ifinyelele i-<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> yakho"</string> <string name="profile_name_watch" msgid="576290739483672360">"buka"</string> <string name="chooser_title" msgid="2262294130493605839">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ezophathwa yi-<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string> - <string name="summary_watch" msgid="3002344206574997652">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuthi ihlanganyele nezaziso zakho futhi ifinyelele Ifoni yakho, i-SMS, Oxhumana nabo, Ikhalenda, Amarekhodi wamakholi Nezimvume zamadivayisi aseduze."</string> - <string name="permission_apps" msgid="6142133265286656158">"Ama-app"</string> - <string name="permission_apps_summary" msgid="798718816711515431">"Sakaza ama-app wefoni yakho"</string> + <!-- no translation found for summary_watch (4085794790142204006) --> + <skip /> + <!-- no translation found for summary_watch_single_device (1523091550243476756) --> + <skip /> <string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifinyelele lolu lwazi kusukela efonini yakho"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string> <string name="helper_summary_app_streaming" msgid="5977509499890099">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string> @@ -30,10 +31,6 @@ <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Vumela <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukufinyelela lolu lwazi kusuka efonini yakho"</string> <string name="summary_computer" msgid="3798467601598297062"></string> - <string name="permission_notification" msgid="693762568127741203">"Izaziso"</string> - <string name="permission_notification_summary" msgid="884075314530071011">"Ingafunda zonke izaziso, okubandakanya ulwazi olufana noxhumana nabo, imilayezo, nezithombe"</string> - <string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string> - <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string> <string name="helper_summary_computer" msgid="9050724687678157852">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze ifinyelele izithombe zefoni yakho, imidiya nezaziso"</string> <string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string> @@ -45,4 +42,29 @@ <string name="permission_sync_summary" msgid="4866838188678457084">"<p>Lokhu kungase kuhlanganisa Imakrofoni, Ikhamera, kanye Nokufinyelela kwendawo, kanye nezinye izimvume ezibucayi <strong>ku-<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>.</p> <p>Ungashintsha lezi zimvume nganoma yisiphi isikhathi Kumasethingi akho <strong>ku-<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>.</p>"</string> <string name="vendor_icon_description" msgid="4445875290032225965">"Isithonjana Se-app"</string> <string name="vendor_header_button_description" msgid="6566660389500630608">"Inkinobho Yolwazi Olwengeziwe"</string> + <!-- no translation found for permission_phone (2661081078692784919) --> + <skip /> + <!-- no translation found for permission_sms (6337141296535774786) --> + <skip /> + <!-- no translation found for permission_contacts (3858319347208004438) --> + <skip /> + <!-- no translation found for permission_calendar (6805668388691290395) --> + <skip /> + <!-- no translation found for permission_nearby_devices (7530973297737123481) --> + <skip /> + <string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string> + <string name="permission_notification" msgid="693762568127741203">"Izaziso"</string> + <!-- no translation found for permission_app_streaming (6009695219091526422) --> + <skip /> + <!-- no translation found for permission_phone_summary (6154198036705702389) --> + <skip /> + <string name="permission_sms_summary" msgid="5107174184224165570"></string> + <!-- no translation found for permission_contacts_summary (7850901746005070792) --> + <skip /> + <string name="permission_calendar_summary" msgid="9070743747408808156"></string> + <string name="permission_nearby_devices_summary" msgid="8587497797301075494"></string> + <string name="permission_notification_summary" msgid="884075314530071011">"Ingafunda zonke izaziso, okubandakanya ulwazi olufana noxhumana nabo, imilayezo, nezithombe"</string> + <!-- no translation found for permission_app_streaming_summary (606923325679670624) --> + <skip /> + <string name="permission_storage_summary" msgid="3918240895519506417"></string> </resources> diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml index 2934b01e437b..094ece75b5df 100644 --- a/packages/PackageInstaller/res/values-am/strings.xml +++ b/packages/PackageInstaller/res/values-am/strings.xml @@ -83,8 +83,7 @@ <string name="app_name_unknown" msgid="6881210203354323926">"ያልታወቀ"</string> <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"ለእርስዎ ደህንነት ሲባል በአሁኑ ጊዜ ጡባዊዎ ከዚህ ምንጭ ያልታወቁ መተግበሪያዎችን እንዲጭን አይፈቀድለትም። ይህን በቅንብሮች ውስጥ መቀየር ይችላሉ።"</string> <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"ለእርስዎ ደህንነት ሲባል በአሁኑ ጊዜ የእርስዎ ቲቪ ከዚህ ምንጭ ያልታወቁ መተግበሪያዎችን እንዲጭን አይፈቀድለትም። ይህን በቅንብሮች ውስጥ መቀየር ይችላሉ።"</string> - <!-- no translation found for untrusted_external_source_warning (7195163388090818636) --> - <skip /> + <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"ለደህንነትዎ ሲባል በአሁኑ ጊዜ የእጅ ሰዓትዎ ያልታወቁ መተግበሪያዎችን ከዚህ ምንጭ እንዲጭን አይፈቀድለትም። ይህን በቅንብሮች ውስጥ መለወጥ ይችላሉ።"</string> <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"ለእርስዎ ደህንነት ሲባል በአሁኑ ጊዜ ስልክዎ ከዚህ ምንጭ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም። ይህን በቅንብሮች ውስጥ መቀየር ይችላሉ።"</string> <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"የእርስዎ ስልክ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይልበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ስልክ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string> <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"የእርስዎ ጡባዊ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ጡባዊ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string> diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml index 82d3013e5046..f765ba9805c8 100644 --- a/packages/PackageInstaller/res/values-lv/strings.xml +++ b/packages/PackageInstaller/res/values-lv/strings.xml @@ -83,8 +83,7 @@ <string name="app_name_unknown" msgid="6881210203354323926">"Nezināma"</string> <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Drošības apsvērumu dēļ jūsu planšetdatorā pašlaik nav atļauts instalēt nezināmas lietotnes no šī avota. Jūs varat to mainīt iestatījumos."</string> <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Drošības apsvērumu dēļ jūsu televizorā pašlaik nav atļauts instalēt nezināmas lietotnes no šī avota. Jūs varat to mainīt iestatījumos."</string> - <!-- no translation found for untrusted_external_source_warning (7195163388090818636) --> - <skip /> + <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"Drošības apsvērumu dēļ jūsu pulkstenī pašlaik nav atļauts instalēt nezināmas lietotnes no šī avota. Šo atļauju varat mainīt iestatījumos."</string> <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Drošības apsvērumu dēļ jūsu tālrunī pašlaik nav atļauts instalēt nezināmas lietotnes no šī avota. Jūs varat to mainīt iestatījumos."</string> <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Jūsu tālrunis un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par tālruņa bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string> <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Jūsu planšetdators un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par planšetdatora bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string> diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml index 953515396f2d..dcad49c15c70 100644 --- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml @@ -83,7 +83,7 @@ <string name="app_name_unknown" msgid="6881210203354323926">"不明"</string> <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"為安全起見,您的平板電腦目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string> <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"為安全起見,您的電視目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string> - <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"為了安全起見,你的智慧手錶目前禁止安裝這個來源的不明應用程式。如要變更,請前往「設定」。"</string> + <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"為安全起見,您的手錶目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string> <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"為安全起見,您的手機目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string> <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"來源不明的應用程式可能會侵害您的手機和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致手機損壞或資料遺失的責任。"</string> <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"來源不明的應用程式可能會侵害您的平板電腦和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致平板電腦損壞或資料遺失的責任。"</string> diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java index e4bdab89532b..88c10365219b 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java @@ -28,7 +28,6 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller; -import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ProviderInfo; @@ -104,10 +103,9 @@ public class InstallStart extends Activity { Intent.EXTRA_INSTALLER_PACKAGE_NAME); if (installerPackageNameFromIntent != null) { final String callingPkgName = getLaunchedFromPackage(); - if (installerPackageNameFromIntent.length() >= SessionParams.MAX_PACKAGE_NAME_LENGTH - || (!TextUtils.equals(installerPackageNameFromIntent, callingPkgName) + if (!TextUtils.equals(installerPackageNameFromIntent, callingPkgName) && mPackageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES, - callingPkgName) != PackageManager.PERMISSION_GRANTED)) { + callingPkgName) != PackageManager.PERMISSION_GRANTED) { Log.e(LOG_TAG, "The given installer package name " + installerPackageNameFromIntent + " is invalid. Remove it."); EventLog.writeEvent(0x534e4554, "236687884", getLaunchedFromUid(), diff --git a/packages/SettingsLib/FooterPreference/Android.bp b/packages/SettingsLib/FooterPreference/Android.bp index 0929706f27ba..bcedf50a873f 100644 --- a/packages/SettingsLib/FooterPreference/Android.bp +++ b/packages/SettingsLib/FooterPreference/Android.bp @@ -23,5 +23,6 @@ android_library { apex_available: [ "//apex_available:platform", "com.android.permission", + "com.android.healthconnect", ], } diff --git a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml index 0123c270c447..71c52d9f4a6a 100644 --- a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml +++ b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml @@ -42,7 +42,7 @@ android:exported="false"> </provider> - <provider android:name="com.android.settingslib.spa.framework.SpaSliceProvider" + <provider android:name="com.android.settingslib.spa.slice.SpaSliceProvider" android:authorities="com.android.spa.gallery.slice.provider" android:exported="true" > <intent-filter> @@ -52,20 +52,20 @@ </provider> <receiver - android:name="com.android.settingslib.spa.framework.SpaSliceBroadcastReceiver" + android:name="com.android.settingslib.spa.slice.SpaSliceBroadcastReceiver" android:exported="false"> </receiver> <activity - android:name="com.android.settingslib.spa.framework.debug.BlankActivity" + android:name="com.android.settingslib.spa.debug.BlankActivity" android:exported="true"> </activity> <activity - android:name="com.android.settingslib.spa.framework.debug.DebugActivity" + android:name="com.android.settingslib.spa.debug.DebugActivity" android:exported="true"> </activity> <provider - android:name="com.android.settingslib.spa.framework.debug.DebugProvider" + android:name="com.android.settingslib.spa.debug.DebugProvider" android:authorities="com.android.spa.gallery.debug.provider" android:enabled="true" android:exported="false"> diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt index 941e7705441b..db4990974e23 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt @@ -17,17 +17,18 @@ package com.android.settingslib.spa.gallery import android.content.Context -import com.android.settingslib.spa.framework.SpaSliceBroadcastReceiver import com.android.settingslib.spa.framework.common.LocalLogger import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository import com.android.settingslib.spa.framework.common.SpaEnvironment import com.android.settingslib.spa.framework.common.createSettingsPage import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider +import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider import com.android.settingslib.spa.gallery.home.HomePageProvider import com.android.settingslib.spa.gallery.page.ArgumentPageProvider import com.android.settingslib.spa.gallery.page.ChartPageProvider import com.android.settingslib.spa.gallery.page.FooterPageProvider import com.android.settingslib.spa.gallery.page.IllustrationPageProvider +import com.android.settingslib.spa.gallery.page.LoadingBarPageProvider import com.android.settingslib.spa.gallery.page.ProgressBarPageProvider import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider import com.android.settingslib.spa.gallery.page.SliderPageProvider @@ -38,6 +39,7 @@ import com.android.settingslib.spa.gallery.preference.SwitchPreferencePageProvid import com.android.settingslib.spa.gallery.preference.TwoTargetSwitchPreferencePageProvider import com.android.settingslib.spa.gallery.ui.CategoryPageProvider import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider +import com.android.settingslib.spa.slice.SpaSliceBroadcastReceiver /** * Enum to define all SPP name here. @@ -71,7 +73,9 @@ class GallerySpaEnvironment(context: Context) : SpaEnvironment(context) { CategoryPageProvider, ActionButtonPageProvider, ProgressBarPageProvider, + LoadingBarPageProvider, ChartPageProvider, + AlterDialogPageProvider, ), rootPages = listOf( HomePageProvider.createSettingsPage(), @@ -79,9 +83,12 @@ class GallerySpaEnvironment(context: Context) : SpaEnvironment(context) { ) } + override val logger = LocalLogger() + override val browseActivityClass = GalleryMainActivity::class.java override val sliceBroadcastReceiverClass = SpaSliceBroadcastReceiver::class.java + + // For debugging override val searchProviderAuthorities = "com.android.spa.gallery.search.provider" override val sliceProviderAuthorities = "com.android.spa.gallery.slice.provider" - override val logger = LocalLogger() } diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/dialog/AlterDialogPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/dialog/AlterDialogPage.kt new file mode 100644 index 000000000000..a57df0f46f6a --- /dev/null +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/dialog/AlterDialogPage.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.gallery.dialog + +import android.os.Bundle +import androidx.compose.material3.Text +import com.android.settingslib.spa.framework.common.SettingsEntry +import com.android.settingslib.spa.framework.common.SettingsEntryBuilder +import com.android.settingslib.spa.framework.common.SettingsPageProvider +import com.android.settingslib.spa.framework.common.createSettingsPage +import com.android.settingslib.spa.framework.compose.navigator +import com.android.settingslib.spa.widget.dialog.AlertDialogButton +import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter +import com.android.settingslib.spa.widget.preference.Preference +import com.android.settingslib.spa.widget.preference.PreferenceModel + +private const val TITLE = "AlterDialogPage" + +object AlterDialogPageProvider : SettingsPageProvider { + override val name = "AlterDialogPage" + private val owner = createSettingsPage() + + override fun buildEntry(arguments: Bundle?): List<SettingsEntry> = listOf( + SettingsEntryBuilder.create("AlterDialog", owner).setUiLayoutFn { + val alertDialogPresenter = rememberAlertDialogPresenter( + confirmButton = AlertDialogButton("Ok"), + dismissButton = AlertDialogButton("Cancel"), + title = "Title", + text = { Text("Text") }, + ) + Preference(object : PreferenceModel { + override val title = "Show AlterDialog" + override val onClick = alertDialogPresenter::open + }) + }.build(), + ) + + fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner) + .setIsAllowSearch(true) + .setUiLayoutFn { + Preference(object : PreferenceModel { + override val title = TITLE + override val onClick = navigator(name) + }) + } + + override fun getTitle(arguments: Bundle?) = TITLE +} diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt index 83c72c75e9f3..5d26b3458487 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt @@ -27,11 +27,13 @@ import com.android.settingslib.spa.framework.theme.SettingsTheme import com.android.settingslib.spa.gallery.R import com.android.settingslib.spa.gallery.SettingsPageProviderEnum import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider +import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider import com.android.settingslib.spa.gallery.page.ArgumentPageModel import com.android.settingslib.spa.gallery.page.ArgumentPageProvider import com.android.settingslib.spa.gallery.page.ChartPageProvider import com.android.settingslib.spa.gallery.page.FooterPageProvider import com.android.settingslib.spa.gallery.page.IllustrationPageProvider +import com.android.settingslib.spa.gallery.page.LoadingBarPageProvider import com.android.settingslib.spa.gallery.page.ProgressBarPageProvider import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider import com.android.settingslib.spa.gallery.page.SliderPageProvider @@ -57,7 +59,9 @@ object HomePageProvider : SettingsPageProvider { CategoryPageProvider.buildInjectEntry().setLink(fromPage = owner).build(), ActionButtonPageProvider.buildInjectEntry().setLink(fromPage = owner).build(), ProgressBarPageProvider.buildInjectEntry().setLink(fromPage = owner).build(), + LoadingBarPageProvider.buildInjectEntry().setLink(fromPage = owner).build(), ChartPageProvider.buildInjectEntry().setLink(fromPage = owner).build(), + AlterDialogPageProvider.buildInjectEntry().setLink(fromPage = owner).build(), ) } diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt new file mode 100644 index 000000000000..c354930dc4a8 --- /dev/null +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.gallery.page + +import android.os.Bundle +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.android.settingslib.spa.framework.common.SettingsEntryBuilder +import com.android.settingslib.spa.framework.common.SettingsPage +import com.android.settingslib.spa.framework.common.SettingsPageProvider +import com.android.settingslib.spa.framework.compose.navigator +import com.android.settingslib.spa.framework.theme.SettingsTheme +import com.android.settingslib.spa.widget.preference.Preference +import com.android.settingslib.spa.widget.preference.PreferenceModel +import com.android.settingslib.spa.widget.scaffold.RegularScaffold +import com.android.settingslib.spa.widget.ui.CircularLoadingBar +import com.android.settingslib.spa.widget.ui.LinearLoadingBar + +private const val TITLE = "Sample LoadingBar" + +object LoadingBarPageProvider : SettingsPageProvider { + override val name = "LoadingBar" + + fun buildInjectEntry(): SettingsEntryBuilder { + return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name)) + .setIsAllowSearch(true) + .setUiLayoutFn { + Preference(object : PreferenceModel { + override val title = TITLE + override val onClick = navigator(name) + }) + } + } + + override fun getTitle(arguments: Bundle?): String { + return TITLE + } + + @Composable + override fun Page(arguments: Bundle?) { + var loading by remember { mutableStateOf(true) } + RegularScaffold(title = getTitle(arguments)) { + Button( + onClick = { loading = !loading }, + modifier = Modifier.padding(start = 20.dp) + ) { + if (loading) { + Text(text = "Stop") + } else { + Text(text = "Resume") + } + } + } + + LinearLoadingBar(isLoading = loading, yOffset = 104.dp) + CircularLoadingBar(isLoading = loading) + } +} + +@Preview(showBackground = true) +@Composable +private fun LoadingBarPagePreview() { + SettingsTheme { + LoadingBarPageProvider.Page(null) + } +} diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt index 9136b0430c40..1f76557764a7 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt @@ -27,7 +27,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import com.android.settingslib.spa.framework.common.SettingsEntryBuilder import com.android.settingslib.spa.framework.common.SettingsPage import com.android.settingslib.spa.framework.common.SettingsPageProvider @@ -39,9 +38,7 @@ import com.android.settingslib.spa.widget.preference.ProgressBarPreference import com.android.settingslib.spa.widget.preference.ProgressBarPreferenceModel import com.android.settingslib.spa.widget.preference.ProgressBarWithDataPreference import com.android.settingslib.spa.widget.scaffold.RegularScaffold -import com.android.settingslib.spa.widget.ui.CircularLoadingBar import com.android.settingslib.spa.widget.ui.CircularProgressBar -import com.android.settingslib.spa.widget.ui.LinearLoadingBar import kotlinx.coroutines.delay private const val TITLE = "Sample ProgressBar" @@ -66,18 +63,10 @@ object ProgressBarPageProvider : SettingsPageProvider { @Composable override fun Page(arguments: Bundle?) { - // Mocks a loading time of 2 seconds. - var loading by remember { mutableStateOf(true) } - LaunchedEffect(Unit) { - delay(2000) - loading = false - } - RegularScaffold(title = getTitle(arguments)) { // Auto update the progress and finally jump tp 0.4f. var progress by remember { mutableStateOf(0f) } LaunchedEffect(Unit) { - delay(2000) while (progress < 1f) { delay(100) progress += 0.01f @@ -86,19 +75,11 @@ object ProgressBarPageProvider : SettingsPageProvider { progress = 0.4f } - // Show as a placeholder for progress bar LargeProgressBar(progress) - // The remaining information only shows after loading complete. - if (!loading) { - SimpleProgressBar() - ProgressBarWithData() - CircularProgressBar(progress = progress, radius = 160f) - } + SimpleProgressBar() + ProgressBarWithData() + CircularProgressBar(progress = progress, radius = 160f) } - - // Add loading bar examples, running for 2 seconds. - LinearLoadingBar(isLoading = loading, yOffset = 64.dp) - CircularLoadingBar(isLoading = loading) } } diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt index 367766a34a3c..dab04fdf740a 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt @@ -17,6 +17,8 @@ package com.android.settingslib.spa.gallery.preference import android.os.Bundle +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.AirplanemodeActive import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState @@ -34,6 +36,7 @@ import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel +import com.android.settingslib.spa.widget.ui.SettingsIcon import kotlinx.coroutines.delay private const val TITLE = "Sample SwitchPreference" @@ -72,6 +75,13 @@ object SwitchPreferencePageProvider : SettingsPageProvider { SampleNotChangeableSwitchPreference() }.build() ) + entryList.add( + SettingsEntryBuilder.create( "SwitchPreference with icon", owner) + .setIsAllowSearch(true) + .setUiLayoutFn { + SampleSwitchPreferenceWithIcon() + }.build() + ) return entryList } @@ -148,6 +158,21 @@ private fun SampleNotChangeableSwitchPreference() { }) } +@Composable +private fun SampleSwitchPreferenceWithIcon() { + val checked = rememberSaveable { mutableStateOf(true) } + SwitchPreference(remember { + object : SwitchPreferenceModel { + override val title = "SwitchPreference" + override val checked = checked + override val onCheckedChange = { newChecked: Boolean -> checked.value = newChecked } + override val icon = @Composable { + SettingsIcon(imageVector = Icons.Outlined.AirplanemodeActive) + } + } + }) +} + @Preview(showBackground = true) @Composable private fun SwitchPreferencePagePreview() { diff --git a/packages/SettingsLib/Spa/spa/Android.bp b/packages/SettingsLib/Spa/spa/Android.bp index eb7aaa71fc7b..3ea3b5ccc4f5 100644 --- a/packages/SettingsLib/Spa/spa/Android.bp +++ b/packages/SettingsLib/Spa/spa/Android.bp @@ -33,6 +33,7 @@ android_library { "androidx.compose.runtime_runtime-livedata", "androidx.compose.ui_ui-tooling-preview", "androidx.lifecycle_lifecycle-livedata-ktx", + "androidx.lifecycle_lifecycle-runtime-compose", "androidx.navigation_navigation-compose", "com.google.android.material_material", "lottie_compose", diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle index 854359641bc0..b1d8d0dadfbd 100644 --- a/packages/SettingsLib/Spa/spa/build.gradle +++ b/packages/SettingsLib/Spa/spa/build.gradle @@ -55,6 +55,8 @@ android { } dependencies { + String jetpack_lifecycle_version = "2.6.0-alpha03" + api "androidx.appcompat:appcompat:1.7.0-alpha01" api "androidx.slice:slice-builders:1.1.0-alpha02" api "androidx.slice:slice-core:1.1.0-alpha02" @@ -63,8 +65,9 @@ dependencies { api "androidx.compose.material:material-icons-extended:$jetpack_compose_version" api "androidx.compose.runtime:runtime-livedata:$jetpack_compose_version" api "androidx.compose.ui:ui-tooling-preview:$jetpack_compose_version" - api "androidx.lifecycle:lifecycle-livedata-ktx:2.6.0-alpha03" - api "androidx.navigation:navigation-compose:2.6.0-alpha03" + api "androidx.lifecycle:lifecycle-livedata-ktx:$jetpack_lifecycle_version" + api "androidx.lifecycle:lifecycle-runtime-compose:$jetpack_lifecycle_version" + api "androidx.navigation:navigation-compose:2.6.0-alpha04" api "com.github.PhilJay:MPAndroidChart:v3.1.0-alpha" api "com.google.android.material:material:1.7.0-alpha03" debugApi "androidx.compose.ui:ui-tooling:$jetpack_compose_version" diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt index 760064a7d691..238268a9ee08 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugActivity.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settingslib.spa.framework.debug +package com.android.settingslib.spa.debug import android.net.Uri import android.os.Bundle diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugFormat.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugFormat.kt index 538d2b577bad..58736350dc7f 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugFormat.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugFormat.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settingslib.spa.framework.debug +package com.android.settingslib.spa.debug import com.android.settingslib.spa.framework.common.EntrySearchData import com.android.settingslib.spa.framework.common.EntryStatusData diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugProvider.kt index 399278ded648..3df77277c205 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugProvider.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugProvider.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settingslib.spa.framework.debug +package com.android.settingslib.spa.debug import android.content.ContentProvider import android.content.ContentValues diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt index c3c90ab4fdb8..6ed7481b2400 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt @@ -19,6 +19,7 @@ package com.android.settingslib.spa.framework import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect @@ -37,6 +38,7 @@ import androidx.navigation.compose.rememberNavController import com.android.settingslib.spa.R import com.android.settingslib.spa.framework.common.LogCategory import com.android.settingslib.spa.framework.common.SettingsPage +import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.common.createSettingsPage import com.android.settingslib.spa.framework.compose.LocalNavController @@ -74,86 +76,97 @@ open class BrowseActivity : ComponentActivity() { setContent { SettingsTheme { - MainContent() + val sppRepository by spaEnvironment.pageProviderRepository + BrowseContent( + allProviders = sppRepository.getAllProviders(), + initialDestination = intent?.getStringExtra(KEY_DESTINATION) + ?: sppRepository.getDefaultStartPage(), + initialEntryId = intent?.getStringExtra(KEY_HIGHLIGHT_ENTRY) + ) } } } - @Composable - private fun MainContent() { - val sppRepository by spaEnvironment.pageProviderRepository - val navController = rememberNavController() - val nullPage = SettingsPage.createNull() - CompositionLocalProvider(navController.localNavController()) { - NavHost( - navController = navController, - startDestination = nullPage.sppName, - ) { - composable(nullPage.sppName) {} - for (spp in sppRepository.getAllProviders()) { - composable( - route = spp.name + spp.parameter.navRoute(), - arguments = spp.parameter, - ) { navBackStackEntry -> - PageLogger(remember(navBackStackEntry.arguments) { - spp.createSettingsPage(arguments = navBackStackEntry.arguments) - }) + companion object { + const val KEY_DESTINATION = "spaActivityDestination" + const val KEY_HIGHLIGHT_ENTRY = "highlightEntry" + } +} - spp.Page(navBackStackEntry.arguments) - } - } - } - InitialDestinationNavigator() - } +@VisibleForTesting +@Composable +fun BrowseContent( + allProviders: Collection<SettingsPageProvider>, + initialDestination: String, + initialEntryId: String? +) { + val navController = rememberNavController() + CompositionLocalProvider(navController.localNavController()) { + val controller = LocalNavController.current as NavControllerWrapperImpl + controller.NavContent(allProviders) + controller.InitialDestination(initialDestination, initialEntryId) } +} - @Composable - private fun PageLogger(settingsPage: SettingsPage) { - val lifecycleOwner = LocalLifecycleOwner.current - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_START) { - settingsPage.enterPage() - } else if (event == Lifecycle.Event.ON_STOP) { - settingsPage.leavePage() - } +@Composable +private fun SettingsPageProvider.PageEvents(arguments: Bundle? = null) { + val page = remember(arguments) { createSettingsPage(arguments) } + val lifecycleOwner = LocalLifecycleOwner.current + DisposableEffect(lifecycleOwner) { + val observer = LifecycleEventObserver { _, event -> + if (event == Lifecycle.Event.ON_START) { + page.enterPage() + } else if (event == Lifecycle.Event.ON_STOP) { + page.leavePage() } + } - // Add the observer to the lifecycle - lifecycleOwner.lifecycle.addObserver(observer) + // Add the observer to the lifecycle + lifecycleOwner.lifecycle.addObserver(observer) - // When the effect leaves the Composition, remove the observer - onDispose { - lifecycleOwner.lifecycle.removeObserver(observer) - } + // When the effect leaves the Composition, remove the observer + onDispose { + lifecycleOwner.lifecycle.removeObserver(observer) } } +} - @Composable - private fun InitialDestinationNavigator() { - val sppRepository by spaEnvironment.pageProviderRepository - val destinationNavigated = rememberSaveable { mutableStateOf(false) } - if (destinationNavigated.value) return - destinationNavigated.value = true - val controller = LocalNavController.current as NavControllerWrapperImpl - LaunchedEffect(Unit) { - val destination = - intent?.getStringExtra(KEY_DESTINATION) ?: sppRepository.getDefaultStartPage() - val highlightEntryId = intent?.getStringExtra(KEY_HIGHLIGHT_ENTRY) - if (destination.isNotEmpty()) { - controller.highlightId = highlightEntryId - val navController = controller.navController - navController.navigate(destination) { - popUpTo(navController.graph.findStartDestination().id) { - inclusive = true - } - } +@Composable +private fun NavControllerWrapperImpl.NavContent(allProvider: Collection<SettingsPageProvider>) { + val nullPage = SettingsPage.createNull() + NavHost( + navController = navController, + startDestination = nullPage.sppName, + ) { + composable(nullPage.sppName) {} + for (spp in allProvider) { + composable( + route = spp.name + spp.parameter.navRoute(), + arguments = spp.parameter, + ) { navBackStackEntry -> + spp.PageEvents(navBackStackEntry.arguments) + spp.Page(navBackStackEntry.arguments) } } } +} - companion object { - const val KEY_DESTINATION = "spaActivityDestination" - const val KEY_HIGHLIGHT_ENTRY = "highlightEntry" +@Composable +private fun NavControllerWrapperImpl.InitialDestination( + destination: String, + highlightEntryId: String? +) { + val destinationNavigated = rememberSaveable { mutableStateOf(false) } + if (destinationNavigated.value) return + destinationNavigated.value = true + + if (destination.isEmpty()) return + LaunchedEffect(Unit) { + highlightId = highlightEntryId + navController.navigate(destination) { + popUpTo(navController.graph.findStartDestination().id) { + inclusive = true + } + } } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt index a372bbd3721b..82e05a55a64b 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt @@ -156,6 +156,15 @@ data class SettingsPage( } } +fun SettingsPageProvider.createSettingsPage(arguments: Bundle? = null): SettingsPage { + return SettingsPage.create( + name = name, + displayName = displayName, + parameter = parameter, + arguments = arguments + ) +} + fun String.toHashId(): String { return this.hashCode().toUInt().toString(36) } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt index 60599d49968f..940005d0c514 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt @@ -51,12 +51,3 @@ interface SettingsPageProvider { } } } - -fun SettingsPageProvider.createSettingsPage(arguments: Bundle? = null): SettingsPage { - return SettingsPage.create( - name = name, - displayName = displayName, - parameter = parameter, - arguments = arguments - ) -} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt index 945add47b965..6d0b810d0cb6 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt @@ -70,11 +70,14 @@ abstract class SpaEnvironment(context: Context) { // In Robolectric test, applicationContext is not available. Use context as fallback. val appContext: Context = context.applicationContext ?: context + open val logger: SpaLogger = object : SpaLogger {} + open val browseActivityClass: Class<out Activity>? = null open val sliceBroadcastReceiverClass: Class<out BroadcastReceiver>? = null + + // Specify provider authorities for debugging purpose. open val searchProviderAuthorities: String? = null open val sliceProviderAuthorities: String? = null - open val logger: SpaLogger = object : SpaLogger {} // TODO: add other environment setup here. } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/util/EntryHighlight.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/EntryHighlight.kt index e26bdf76e9d6..90c44b549df9 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/util/EntryHighlight.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/EntryHighlight.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settingslib.spa.widget.util +package com.android.settingslib.spa.framework.util import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.RepeatMode diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/SpaSliceBroadcastReceiver.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceBroadcastReceiver.kt index 58131e69d329..39cb43180f58 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/SpaSliceBroadcastReceiver.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceBroadcastReceiver.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settingslib.spa.framework +package com.android.settingslib.spa.slice import android.content.BroadcastReceiver import android.content.Context diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/SpaSliceProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceProvider.kt index faa04fda1904..b809c0f1ae63 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/SpaSliceProvider.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/slice/SpaSliceProvider.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settingslib.spa.framework +package com.android.settingslib.spa.slice import android.net.Uri import android.util.Log diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialog.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialog.kt new file mode 100644 index 000000000000..d6f5328068ad --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialog.kt @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.widget.dialog + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.DialogProperties + +data class AlertDialogButton( + val text: String, + val onClick: () -> Unit = {}, +) + +interface AlertDialogPresenter { + /** Opens the dialog. */ + fun open() + + /** Closes the dialog. */ + fun close() +} + +@Composable +fun rememberAlertDialogPresenter( + confirmButton: AlertDialogButton? = null, + dismissButton: AlertDialogButton? = null, + title: String? = null, + text: @Composable (() -> Unit)? = null, +): AlertDialogPresenter { + var openDialog by rememberSaveable { mutableStateOf(false) } + val alertDialogPresenter = remember { + object : AlertDialogPresenter { + override fun open() { + openDialog = true + } + + override fun close() { + openDialog = false + } + } + } + if (openDialog) { + alertDialogPresenter.SettingsAlertDialog(confirmButton, dismissButton, title, text) + } + return alertDialogPresenter +} + +@OptIn(ExperimentalComposeUiApi::class) +@Composable +private fun AlertDialogPresenter.SettingsAlertDialog( + confirmButton: AlertDialogButton?, + dismissButton: AlertDialogButton?, + title: String?, + text: @Composable (() -> Unit)?, +) { + val configuration = LocalConfiguration.current + AlertDialog( + onDismissRequest = ::close, + modifier = when (configuration.orientation) { + Configuration.ORIENTATION_LANDSCAPE -> { + Modifier.width(configuration.screenWidthDp.dp * 0.6f) + } + else -> Modifier + }, + confirmButton = { confirmButton?.let { Button(it) } }, + dismissButton = dismissButton?.let { { Button(it) } }, + title = title?.let { { Text(it) } }, + text = text?.let { + { + Column(Modifier.verticalScroll(rememberScrollState())) { + text() + } + } + }, + properties = DialogProperties(usePlatformDefaultWidth = false), + ) +} + +@Composable +private fun AlertDialogPresenter.Button(button: AlertDialogButton) { + TextButton( + onClick = { + close() + button.onClick() + }, + ) { + Text(button.text) + } +} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/MainSwitchPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/MainSwitchPreference.kt index db95e23bb52b..3e04b16f08cf 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/MainSwitchPreference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/MainSwitchPreference.kt @@ -28,7 +28,7 @@ import com.android.settingslib.spa.framework.compose.toState import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.framework.theme.SettingsShape import com.android.settingslib.spa.framework.theme.SettingsTheme -import com.android.settingslib.spa.widget.util.EntryHighlight +import com.android.settingslib.spa.framework.util.EntryHighlight @Composable fun MainSwitchPreference(model: SwitchPreferenceModel) { diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt index 895edf77b3cc..77c564b6ec15 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt @@ -27,9 +27,9 @@ import com.android.settingslib.spa.framework.common.EntrySearchData import com.android.settingslib.spa.framework.common.EntryStatusData import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.stateOf +import com.android.settingslib.spa.framework.util.EntryHighlight import com.android.settingslib.spa.framework.util.wrapOnClickWithLog import com.android.settingslib.spa.widget.ui.createSettingsIcon -import com.android.settingslib.spa.widget.util.EntryHighlight data class SimplePreferenceMacro( val title: String, diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SliderPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SliderPreference.kt index 4ee2af0fa1b7..7bca38fdb48f 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SliderPreference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SliderPreference.kt @@ -31,8 +31,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.tooling.preview.Preview import com.android.settingslib.spa.framework.theme.SettingsTheme +import com.android.settingslib.spa.framework.util.EntryHighlight import com.android.settingslib.spa.widget.ui.SettingsSlider -import com.android.settingslib.spa.widget.util.EntryHighlight /** * The widget model for [SliderPreference] widget. diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SwitchPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SwitchPreference.kt index 2d606193872d..b67eb3d59645 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SwitchPreference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/SwitchPreference.kt @@ -20,6 +20,8 @@ import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Column import androidx.compose.foundation.selection.toggleable +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.AirplanemodeActive import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.remember @@ -31,9 +33,10 @@ import com.android.settingslib.spa.framework.compose.stateOf import com.android.settingslib.spa.framework.compose.toState import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.framework.theme.SettingsTheme +import com.android.settingslib.spa.framework.util.EntryHighlight import com.android.settingslib.spa.framework.util.wrapOnSwitchWithLog +import com.android.settingslib.spa.widget.ui.SettingsIcon import com.android.settingslib.spa.widget.ui.SettingsSwitch -import com.android.settingslib.spa.widget.util.EntryHighlight /** * The widget model for [SwitchPreference] widget. @@ -51,6 +54,14 @@ interface SwitchPreferenceModel { get() = stateOf("") /** + * The icon of this [Preference]. + * + * Default is `null` which means no icon. + */ + val icon: (@Composable () -> Unit)? + get() = null + + /** * Indicates whether this [SwitchPreference] is checked. * * This can be `null` during the data loading before the data is available. @@ -84,6 +95,7 @@ fun SwitchPreference(model: SwitchPreferenceModel) { InternalSwitchPreference( title = model.title, summary = model.summary, + icon = model.icon, checked = model.checked, changeable = model.changeable, onCheckedChange = model.onCheckedChange, @@ -95,6 +107,7 @@ fun SwitchPreference(model: SwitchPreferenceModel) { internal fun InternalSwitchPreference( title: String, summary: State<String> = "".toState(), + icon: @Composable (() -> Unit)? = null, checked: State<Boolean?>, changeable: State<Boolean> = true.toState(), paddingStart: Dp = SettingsDimension.itemPaddingStart, @@ -125,6 +138,7 @@ internal fun InternalSwitchPreference( paddingStart = paddingStart, paddingEnd = paddingEnd, paddingVertical = paddingVertical, + icon = icon, ) { SettingsSwitch( checked = checked, @@ -152,6 +166,15 @@ private fun SwitchPreferencePreview() { checked = false.toState(), onCheckedChange = {}, ) + InternalSwitchPreference( + title = "Use Dark theme", + summary = "Summary".toState(), + checked = true.toState(), + onCheckedChange = {}, + icon = @Composable { + SettingsIcon(imageVector = Icons.Outlined.AirplanemodeActive) + }, + ) } } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt index fbfcaaa28047..63de2c821154 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt @@ -17,7 +17,7 @@ package com.android.settingslib.spa.widget.preference import androidx.compose.runtime.Composable -import com.android.settingslib.spa.widget.util.EntryHighlight +import com.android.settingslib.spa.framework.util.EntryHighlight import com.android.settingslib.spa.widget.ui.SettingsSwitch @Composable diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt index 5e201dfccbd5..84fea158175f 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt @@ -17,7 +17,6 @@ package com.android.settingslib.spa.widget.scaffold import androidx.appcompat.R -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.MoreVert import androidx.compose.material3.DropdownMenu @@ -36,7 +35,7 @@ import androidx.compose.ui.res.stringResource /** * Scope for the children of [MoreOptionsAction]. */ -interface MoreOptionsScope : ColumnScope { +interface MoreOptionsScope { fun dismiss() @Composable @@ -61,7 +60,7 @@ fun MoreOptionsAction( val onDismiss = { expanded = false } DropdownMenu(expanded = expanded, onDismissRequest = onDismiss) { val moreOptionsScope = remember(this) { - object : MoreOptionsScope, ColumnScope by this { + object : MoreOptionsScope { override fun dismiss() { onDismiss() } diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/BrowseActivityTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/BrowseActivityTest.kt new file mode 100644 index 000000000000..bde3bba149a3 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/BrowseActivityTest.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.framework + +import android.content.Context +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onAllNodesWithText +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.framework.common.LogCategory +import com.android.settingslib.spa.framework.common.LogEvent +import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory +import com.android.settingslib.spa.framework.common.createSettingsPage +import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest +import com.android.settingslib.spa.tests.testutils.SpaLoggerForTest +import com.android.settingslib.spa.testutils.waitUntil +import com.google.common.truth.Truth +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +const val WAIT_UNTIL_TIMEOUT = 1000L + +@RunWith(AndroidJUnit4::class) +class BrowseActivityTest { + @get:Rule + val composeTestRule = createComposeRule() + + private val context: Context = ApplicationProvider.getApplicationContext() + private val spaLogger = SpaLoggerForTest() + private val spaEnvironment = SpaEnvironmentForTest(context, logger = spaLogger) + + @Test + fun testBrowsePage() { + spaLogger.reset() + SpaEnvironmentFactory.reset(spaEnvironment) + + val sppRepository by spaEnvironment.pageProviderRepository + val sppHome = sppRepository.getProviderOrNull("SppHome")!! + val pageHome = sppHome.createSettingsPage() + val sppLayer1 = sppRepository.getProviderOrNull("SppLayer1")!! + val pageLayer1 = sppLayer1.createSettingsPage() + + composeTestRule.setContent { + BrowseContent( + allProviders = listOf(sppHome, sppLayer1), + initialDestination = pageHome.buildRoute(), + initialEntryId = null + ) + } + + composeTestRule.onNodeWithText(sppHome.getTitle(null)).assertIsDisplayed() + spaLogger.verifyPageEvent(pageHome.id, 1, 0) + spaLogger.verifyPageEvent(pageLayer1.id, 0, 0) + + // click to layer1 page + composeTestRule.onNodeWithText("SppHome to Layer1").assertIsDisplayed().performClick() + waitUntil(WAIT_UNTIL_TIMEOUT) { + composeTestRule.onAllNodesWithText(sppLayer1.getTitle(null)) + .fetchSemanticsNodes().size == 1 + } + spaLogger.verifyPageEvent(pageHome.id, 1, 1) + spaLogger.verifyPageEvent(pageLayer1.id, 1, 0) + } +} + +private fun SpaLoggerForTest.verifyPageEvent(id: String, entryCount: Int, leaveCount: Int) { + Truth.assertThat(getEventCount(id, LogEvent.PAGE_ENTER, LogCategory.FRAMEWORK)) + .isEqualTo(entryCount) + Truth.assertThat(getEventCount(id, LogEvent.PAGE_LEAVE, LogCategory.FRAMEWORK)) + .isEqualTo(leaveCount) +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt index 9419161fe48d..f8339b6dd99b 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt @@ -19,6 +19,10 @@ package com.android.settingslib.spa.framework.common import android.content.Context import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest +import com.android.settingslib.spa.tests.testutils.SppHome +import com.android.settingslib.spa.tests.testutils.SppLayer1 +import com.android.settingslib.spa.tests.testutils.SppLayer2 import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt index 7097a5da4268..743b5e3df2f6 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt @@ -22,6 +22,9 @@ import androidx.navigation.NavType import androidx.navigation.navArgument import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.tests.testutils.BlankActivity +import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest +import com.android.settingslib.spa.tests.testutils.SpaLoggerForTest import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @@ -42,9 +45,9 @@ class SettingsPageTest { assertThat(page.isCreateBy("NULL")).isTrue() assertThat(page.isCreateBy("Spp")).isFalse() assertThat(page.hasRuntimeParam()).isFalse() - assertThat(page.isBrowsable(context, MockActivity::class.java)).isFalse() - assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNull() - assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).isNull() + assertThat(page.isBrowsable(context, BlankActivity::class.java)).isFalse() + assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNull() + assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).isNull() } @Test @@ -57,9 +60,9 @@ class SettingsPageTest { assertThat(page.isCreateBy("NULL")).isFalse() assertThat(page.isCreateBy("mySpp")).isTrue() assertThat(page.hasRuntimeParam()).isFalse() - assertThat(page.isBrowsable(context, MockActivity::class.java)).isTrue() - assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNotNull() - assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).contains( + assertThat(page.isBrowsable(context, BlankActivity::class.java)).isTrue() + assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNotNull() + assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).contains( "-e spaActivityDestination mySpp" ) } @@ -80,9 +83,9 @@ class SettingsPageTest { assertThat(page.buildRoute()).isEqualTo("SppWithParam/myStr/10") assertThat(page.isCreateBy("SppWithParam")).isTrue() assertThat(page.hasRuntimeParam()).isFalse() - assertThat(page.isBrowsable(context, MockActivity::class.java)).isTrue() - assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNotNull() - assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).contains( + assertThat(page.isBrowsable(context, BlankActivity::class.java)).isTrue() + assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNotNull() + assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).contains( "-e spaActivityDestination SppWithParam/myStr/10" ) } @@ -105,9 +108,9 @@ class SettingsPageTest { assertThat(page.buildRoute()).isEqualTo("SppWithRtParam/myStr/10/rtStr") assertThat(page.isCreateBy("SppWithRtParam")).isTrue() assertThat(page.hasRuntimeParam()).isTrue() - assertThat(page.isBrowsable(context, MockActivity::class.java)).isFalse() - assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNull() - assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).isNull() + assertThat(page.isBrowsable(context, BlankActivity::class.java)).isFalse() + assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNull() + assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).isNull() } @Test diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt new file mode 100644 index 000000000000..6ebd64f25e48 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.slice + +import android.content.Context +import android.net.Uri +import androidx.lifecycle.Observer +import androidx.slice.Slice +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.framework.common.createSettingsPage +import com.android.settingslib.spa.framework.common.getUniqueEntryId +import com.android.settingslib.spa.testutils.InstantTaskExecutorRule +import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest +import com.android.settingslib.spa.tests.testutils.SppLayer2 +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SettingsSliceDataRepositoryTest { + @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() + + private val context: Context = ApplicationProvider.getApplicationContext() + private val spaEnvironment = SpaEnvironmentForTest(context) + private val sliceDataRepository by spaEnvironment.sliceDataRepository + + @Test + fun getOrBuildSliceDataTest() { + // Slice empty + assertThat(sliceDataRepository.getOrBuildSliceData(Uri.EMPTY)).isNull() + + // Slice supported + val page = SppLayer2.createSettingsPage() + val entryId = getUniqueEntryId("Layer2Entry1", page) + val sliceUri = Uri.Builder().appendSliceParams(page.buildRoute(), entryId).build() + assertThat(sliceUri.getDestination()).isEqualTo("SppLayer2") + assertThat(sliceUri.getSliceId()).isEqualTo("${entryId}_Bundle[{}]") + val sliceData = sliceDataRepository.getOrBuildSliceData(sliceUri) + assertThat(sliceData).isNotNull() + assertThat(sliceDataRepository.getOrBuildSliceData(sliceUri)).isSameInstanceAs(sliceData) + + // Slice unsupported + val entryId2 = getUniqueEntryId("Layer2Entry2", page) + val sliceUri2 = Uri.Builder().appendSliceParams(page.buildRoute(), entryId2).build() + assertThat(sliceUri2.getDestination()).isEqualTo("SppLayer2") + assertThat(sliceUri2.getSliceId()).isEqualTo("${entryId2}_Bundle[{}]") + assertThat(sliceDataRepository.getOrBuildSliceData(sliceUri2)).isNull() + } + + @Test + fun getActiveSliceDataTest() { + val page = SppLayer2.createSettingsPage() + val entryId = getUniqueEntryId("Layer2Entry1", page) + val sliceUri = Uri.Builder().appendSliceParams(page.buildRoute(), entryId).build() + + // build slice data first + val sliceData = sliceDataRepository.getOrBuildSliceData(sliceUri) + + // slice data is inactive + assertThat(sliceData!!.isActive()).isFalse() + assertThat(sliceDataRepository.getActiveSliceData(sliceUri)).isNull() + + // slice data is active + val observer = Observer<Slice?> { } + sliceData.observeForever(observer) + assertThat(sliceData.isActive()).isTrue() + assertThat(sliceDataRepository.getActiveSliceData(sliceUri)).isSameInstanceAs(sliceData) + + // slice data is inactive again + sliceData.removeObserver(observer) + assertThat(sliceData.isActive()).isFalse() + assertThat(sliceDataRepository.getActiveSliceData(sliceUri)).isNull() + } +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt new file mode 100644 index 000000000000..16a87f603447 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SliceUtilTest.kt @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.slice + +import android.content.Context +import android.content.Intent +import android.net.Uri +import androidx.core.os.bundleOf +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory +import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SliceUtilTest { + private val context: Context = ApplicationProvider.getApplicationContext() + private val spaEnvironment = SpaEnvironmentForTest(context) + + @Test + fun sliceUriTest() { + assertThat(Uri.EMPTY.getEntryId()).isNull() + assertThat(Uri.EMPTY.getDestination()).isNull() + assertThat(Uri.EMPTY.getRuntimeArguments().size()).isEqualTo(0) + assertThat(Uri.EMPTY.getSliceId()).isNull() + + // valid slice uri + val dest = "myRoute" + val entryId = "myEntry" + val sliceUriWithoutParams = Uri.Builder().appendSliceParams(dest, entryId).build() + assertThat(sliceUriWithoutParams.getEntryId()).isEqualTo(entryId) + assertThat(sliceUriWithoutParams.getDestination()).isEqualTo(dest) + assertThat(sliceUriWithoutParams.getRuntimeArguments().size()).isEqualTo(0) + assertThat(sliceUriWithoutParams.getSliceId()).isEqualTo("${entryId}_Bundle[{}]") + + val sliceUriWithParams = + Uri.Builder().appendSliceParams(dest, entryId, bundleOf("p1" to "v1")).build() + assertThat(sliceUriWithParams.getEntryId()).isEqualTo(entryId) + assertThat(sliceUriWithParams.getDestination()).isEqualTo(dest) + assertThat(sliceUriWithParams.getRuntimeArguments().size()).isEqualTo(1) + assertThat(sliceUriWithParams.getSliceId()).isEqualTo("${entryId}_Bundle[{p1=v1}]") + } + + @Test + fun createBroadcastPendingIntentTest() { + SpaEnvironmentFactory.reset(spaEnvironment) + + // Empty Slice Uri + assertThat(Uri.EMPTY.createBroadcastPendingIntent()).isNull() + + // Valid Slice Uri + val dest = "myRoute" + val entryId = "myEntry" + val sliceUriWithoutParams = Uri.Builder().appendSliceParams(dest, entryId).build() + val pendingIntent = sliceUriWithoutParams.createBroadcastPendingIntent() + assertThat(pendingIntent).isNotNull() + assertThat(pendingIntent!!.isBroadcast).isTrue() + assertThat(pendingIntent.isImmutable).isFalse() + } + + @Test + fun createBrowsePendingIntentTest() { + SpaEnvironmentFactory.reset(spaEnvironment) + + // Empty Slice Uri + assertThat(Uri.EMPTY.createBrowsePendingIntent()).isNull() + + // Empty Intent + assertThat(Intent().createBrowsePendingIntent()).isNull() + + // Valid Slice Uri + val dest = "myRoute" + val entryId = "myEntry" + val sliceUri = Uri.Builder().appendSliceParams(dest, entryId).build() + val pendingIntent = sliceUri.createBrowsePendingIntent() + assertThat(pendingIntent).isNotNull() + assertThat(pendingIntent!!.isActivity).isTrue() + assertThat(pendingIntent.isImmutable).isTrue() + + // Valid Intent + val intent = Intent().apply { + putExtra("spaActivityDestination", dest) + putExtra("highlightEntry", entryId) + } + val pendingIntent2 = intent.createBrowsePendingIntent() + assertThat(pendingIntent2).isNotNull() + assertThat(pendingIntent2!!.isActivity).isTrue() + assertThat(pendingIntent2.isImmutable).isTrue() + } +}
\ No newline at end of file diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SpaEnvironmentForTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SpaEnvironmentForTest.kt index b8731a3019f8..ab269f2f024a 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SpaEnvironmentForTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SpaEnvironmentForTest.kt @@ -14,14 +14,28 @@ * limitations under the License. */ -package com.android.settingslib.spa.framework.common +package com.android.settingslib.spa.tests.testutils import android.app.Activity +import android.content.BroadcastReceiver import android.content.Context +import android.content.Intent import android.os.Bundle import androidx.navigation.NavType import androidx.navigation.navArgument import com.android.settingslib.spa.framework.BrowseActivity +import com.android.settingslib.spa.framework.common.EntrySliceData +import com.android.settingslib.spa.framework.common.LogCategory +import com.android.settingslib.spa.framework.common.LogEvent +import com.android.settingslib.spa.framework.common.SettingsEntry +import com.android.settingslib.spa.framework.common.SettingsEntryBuilder +import com.android.settingslib.spa.framework.common.SettingsPage +import com.android.settingslib.spa.framework.common.SettingsPageProvider +import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository +import com.android.settingslib.spa.framework.common.SpaEnvironment +import com.android.settingslib.spa.framework.common.SpaLogger +import com.android.settingslib.spa.framework.common.createSettingsPage +import com.android.settingslib.spa.widget.preference.SimplePreferenceMacro class SpaLoggerForTest : SpaLogger { data class MsgCountKey(val msg: String, val category: LogCategory) @@ -32,22 +46,22 @@ class SpaLoggerForTest : SpaLogger { override fun message(tag: String, msg: String, category: LogCategory) { val key = MsgCountKey("[$tag]$msg", category) - messageCount[key] = messageCount.getOrDefault(key, 0) + 1 + messageCount[key] = (messageCount[key] ?: 0) + 1 } override fun event(id: String, event: LogEvent, category: LogCategory, details: String?) { val key = EventCountKey(id, event, category) - eventCount[key] = eventCount.getOrDefault(key, 0) + 1 + eventCount[key] = (eventCount[key] ?: 0) + 1 } fun getMessageCount(tag: String, msg: String, category: LogCategory): Int { val key = MsgCountKey("[$tag]$msg", category) - return messageCount.getOrDefault(key, 0) + return messageCount[key] ?: 0 } fun getEventCount(id: String, event: LogEvent, category: LogCategory): Int { val key = EventCountKey(id, event, category) - return eventCount.getOrDefault(key, 0) + return eventCount[key] ?: 0 } fun reset() { @@ -56,7 +70,10 @@ class SpaLoggerForTest : SpaLogger { } } -class MockActivity : BrowseActivity() +class BlankActivity : BrowseActivity() +class BlankSliceBroadcastReceiver : BroadcastReceiver() { + override fun onReceive(p0: Context?, p1: Intent?) {} +} object SppHome : SettingsPageProvider { override val name = "SppHome" @@ -82,6 +99,12 @@ object SppLayer1 : SettingsPageProvider { fun buildInject(): SettingsEntryBuilder { return SettingsEntryBuilder.createInject(this.createSettingsPage()) + .setMacro { + SimplePreferenceMacro( + title = "SppHome to Layer1", + clickRoute = name + ) + } } override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { @@ -104,7 +127,15 @@ object SppLayer2 : SettingsPageProvider { override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { val owner = this.createSettingsPage() return listOf( - SettingsEntryBuilder.create(owner, "Layer2Entry1").build(), + SettingsEntryBuilder.create(owner, "Layer2Entry1") + .setSliceDataFn { _, _ -> + return@setSliceDataFn object : EntrySliceData() { + init { + postValue(null) + } + } + } + .build(), SettingsEntryBuilder.create(owner, "Layer2Entry2").build(), ) } @@ -112,8 +143,10 @@ object SppLayer2 : SettingsPageProvider { class SpaEnvironmentForTest( context: Context, - override val browseActivityClass: Class<out Activity>? = MockActivity::class.java, - override val logger: SpaLogger = SpaLoggerForTest() + override val browseActivityClass: Class<out Activity>? = BlankActivity::class.java, + override val sliceBroadcastReceiverClass: Class<out BroadcastReceiver>? = + BlankSliceBroadcastReceiver::class.java, + override val logger: SpaLogger = object : SpaLogger {} ) : SpaEnvironment(context) { override val pageProviderRepository = lazy { diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialogTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialogTest.kt new file mode 100644 index 000000000000..9468f95a094e --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialogTest.kt @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.widget.dialog + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.testutils.onDialogText +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SettingsAlertDialogTest { + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun title_whenDialogNotOpen_notDisplayed() { + composeTestRule.setContent { + rememberAlertDialogPresenter(title = TITLE) + } + + composeTestRule.onDialogText(TITLE).assertDoesNotExist() + } + + @Test + fun title_displayed() { + setAndOpenDialog { + rememberAlertDialogPresenter(title = TITLE) + } + + composeTestRule.onDialogText(TITLE).assertIsDisplayed() + } + + @Test + fun text_displayed() { + setAndOpenDialog { + rememberAlertDialogPresenter(text = { Text(TEXT) }) + } + + composeTestRule.onDialogText(TEXT).assertIsDisplayed() + } + + @Test + fun confirmButton_displayed() { + setAndOpenDialog { + rememberAlertDialogPresenter(confirmButton = AlertDialogButton(CONFIRM_TEXT)) + } + + composeTestRule.onDialogText(CONFIRM_TEXT).assertIsDisplayed() + } + + @Test + fun confirmButton_clickable() { + var confirmButtonClicked = false + setAndOpenDialog { + rememberAlertDialogPresenter(confirmButton = AlertDialogButton(CONFIRM_TEXT) { + confirmButtonClicked = true + }) + } + + composeTestRule.onDialogText(CONFIRM_TEXT).performClick() + + assertThat(confirmButtonClicked).isTrue() + } + + @Test + fun dismissButton_displayed() { + setAndOpenDialog { + rememberAlertDialogPresenter(dismissButton = AlertDialogButton(DISMISS_TEXT)) + } + + composeTestRule.onDialogText(DISMISS_TEXT).assertIsDisplayed() + } + + @Test + fun dismissButton_clickable() { + var dismissButtonClicked = false + setAndOpenDialog { + rememberAlertDialogPresenter(dismissButton = AlertDialogButton(DISMISS_TEXT) { + dismissButtonClicked = true + }) + } + + composeTestRule.onDialogText(DISMISS_TEXT).performClick() + + assertThat(dismissButtonClicked).isTrue() + } + + private fun setAndOpenDialog(dialog: @Composable () -> AlertDialogPresenter) { + composeTestRule.setContent { + val dialogPresenter = dialog() + LaunchedEffect(Unit) { + dialogPresenter.open() + } + } + } + + private companion object { + const val CONFIRM_TEXT = "Confirm" + const val DISMISS_TEXT = "Dismiss" + const val TITLE = "Title" + const val TEXT = "Text" + } +} diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp index 0f618fab9656..48df569f1c54 100644 --- a/packages/SettingsLib/Spa/testutils/Android.bp +++ b/packages/SettingsLib/Spa/testutils/Android.bp @@ -24,6 +24,7 @@ android_library { srcs: ["src/**/*.kt"], static_libs: [ + "androidx.arch.core_core-runtime", "androidx.compose.ui_ui-test-junit4", "androidx.compose.ui_ui-test-manifest", "mockito", diff --git a/packages/SettingsLib/Spa/testutils/build.gradle b/packages/SettingsLib/Spa/testutils/build.gradle index 58b4d42b604a..be8df436712d 100644 --- a/packages/SettingsLib/Spa/testutils/build.gradle +++ b/packages/SettingsLib/Spa/testutils/build.gradle @@ -47,6 +47,7 @@ android { } dependencies { + api "androidx.arch.core:core-runtime:2.1.0" api "androidx.compose.ui:ui-test-junit4:$jetpack_compose_version" api "com.google.truth:truth:1.1.3" api "org.mockito:mockito-core:2.21.0" diff --git a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/InstantTaskExecutorRule.kt b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/InstantTaskExecutorRule.kt new file mode 100644 index 000000000000..43c18d4a3e93 --- /dev/null +++ b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/InstantTaskExecutorRule.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.testutils + +import androidx.arch.core.executor.ArchTaskExecutor +import androidx.arch.core.executor.TaskExecutor +import org.junit.rules.TestWatcher +import org.junit.runner.Description + +/** + * Test rule that makes ArchTaskExecutor main thread assertions pass. There is one such assert + * in LifecycleRegistry. + + * This is a copy of androidx/arch/core/executor/testing/InstantTaskExecutorRule which should be + * replaced once the dependency issue is solved. + */ +class InstantTaskExecutorRule : TestWatcher() { + override fun starting(description: Description) { + super.starting(description) + ArchTaskExecutor.getInstance().setDelegate( + object : TaskExecutor() { + override fun executeOnDiskIO(runnable: Runnable) { + runnable.run() + } + + override fun postToMainThread(runnable: Runnable) { + runnable.run() + } + + override fun isMainThread(): Boolean { + return true + } + } + ) + } + + override fun finished(description: Description) { + super.finished(description) + ArchTaskExecutor.getInstance().setDelegate(null) + } +} diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt index bb1cd6e44867..76f6611a6690 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt @@ -16,6 +16,7 @@ package com.android.settingslib.spaprivileged.framework.common +import android.app.ActivityManager import android.app.AlarmManager import android.app.AppOpsManager import android.app.admin.DevicePolicyManager @@ -28,6 +29,9 @@ import android.os.UserHandle import android.os.UserManager import android.permission.PermissionControllerManager +/** The [ActivityManager] instance. */ +val Context.activityManager get() = getSystemService(ActivityManager::class.java)!! + /** The [AlarmManager] instance. */ val Context.alarmManager get() = getSystemService(AlarmManager::class.java)!! diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt index b1adc9d27a88..a618c3d0575b 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt @@ -20,27 +20,41 @@ import android.app.admin.DevicePolicyResources.Strings.Settings import android.content.Context import android.os.UserHandle import android.os.UserManager -import androidx.lifecycle.liveData +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.android.settingslib.RestrictedLockUtils import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin import com.android.settingslib.RestrictedLockUtilsInternal import com.android.settingslib.spaprivileged.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn data class Restrictions( val userId: Int, val keys: List<String>, ) -sealed class RestrictedMode +sealed interface RestrictedMode -object NoRestricted : RestrictedMode() +object NoRestricted : RestrictedMode -object BaseUserRestricted : RestrictedMode() +object BaseUserRestricted : RestrictedMode -data class BlockedByAdmin( - val enterpriseRepository: EnterpriseRepository, - val enforcedAdmin: EnforcedAdmin, -) : RestrictedMode() { - fun getSummary(checked: Boolean?): String = when (checked) { +interface BlockedByAdmin : RestrictedMode { + fun getSummary(checked: Boolean?): String + fun sendShowAdminSupportDetailsIntent() +} + +private data class BlockedByAdminImpl( + private val context: Context, + private val enforcedAdmin: EnforcedAdmin, +) : BlockedByAdmin { + private val enterpriseRepository by lazy { EnterpriseRepository(context) } + + override fun getSummary(checked: Boolean?) = when (checked) { true -> enterpriseRepository.getEnterpriseString( Settings.ENABLED_BY_ADMIN_SWITCH_SUMMARY, R.string.enabled_by_admin ) @@ -49,18 +63,31 @@ data class BlockedByAdmin( ) else -> "" } + + override fun sendShowAdminSupportDetailsIntent() { + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, enforcedAdmin) + } +} + +interface RestrictionsProvider { + @Composable + fun restrictedModeState(): State<RestrictedMode?> } -class RestrictionsProvider( +internal class RestrictionsProviderImpl( private val context: Context, private val restrictions: Restrictions, -) { +) : RestrictionsProvider { private val userManager by lazy { UserManager.get(context) } - private val enterpriseRepository by lazy { EnterpriseRepository(context) } - val restrictedMode = liveData { + private val restrictedMode = flow { emit(getRestrictedMode()) - } + }.flowOn(Dispatchers.IO) + + @OptIn(ExperimentalLifecycleComposeApi::class) + @Composable + override fun restrictedModeState() = + restrictedMode.collectAsStateWithLifecycle(initialValue = null) private fun getRestrictedMode(): RestrictedMode { for (key in restrictions.keys) { @@ -71,12 +98,7 @@ class RestrictionsProvider( for (key in restrictions.keys) { RestrictedLockUtilsInternal .checkIfRestrictionEnforced(context, key, restrictions.userId) - ?.let { - return BlockedByAdmin( - enterpriseRepository = enterpriseRepository, - enforcedAdmin = it, - ) - } + ?.let { return BlockedByAdminImpl(context = context, enforcedAdmin = it) } } return NoRestricted } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt index ec7d75e969df..6db27336b67f 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt @@ -22,7 +22,6 @@ import android.os.Bundle import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -43,7 +42,7 @@ import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppRecord import com.android.settingslib.spaprivileged.model.app.userId import com.android.settingslib.spaprivileged.model.enterprise.Restrictions -import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreference import kotlinx.coroutines.flow.Flow @@ -146,9 +145,7 @@ internal class TogglePermissionInternalAppListModel<T : AppRecord>( listModel.filter(userIdFlow, recordListFlow) @Composable - override fun getSummary(option: Int, record: T): State<String> { - return getSummary(record) - } + override fun getSummary(option: Int, record: T) = getSummary(record) @Composable fun getSummary(record: T): State<String> { @@ -157,27 +154,27 @@ internal class TogglePermissionInternalAppListModel<T : AppRecord>( userId = record.app.userId, keys = listModel.switchRestrictionKeys, ) - RestrictionsProvider(context, restrictions) + RestrictionsProviderImpl(context, restrictions) } - val restrictedMode = restrictionsProvider.restrictedMode.observeAsState() + val restrictedMode = restrictionsProvider.restrictedModeState() val allowed = listModel.isAllowed(record) return remember { derivedStateOf { RestrictedSwitchPreference.getSummary( context = context, restrictedMode = restrictedMode.value, - noRestrictedSummary = getNoRestrictedSummary(allowed), + summaryIfNoRestricted = getSummaryIfNoRestricted(allowed), checked = allowed, ).value } } } - private fun getNoRestrictedSummary(allowed: State<Boolean?>) = derivedStateOf { + private fun getSummaryIfNoRestricted(allowed: State<Boolean?>) = derivedStateOf { when (allowed.value) { true -> context.getString(R.string.app_permission_summary_allowed) false -> context.getString(R.string.app_permission_summary_not_allowed) - else -> context.getString(R.string.summary_placeholder) + null -> context.getString(R.string.summary_placeholder) } } } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt index 31fd3ad6d521..a003da81e06d 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt @@ -22,12 +22,13 @@ import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.semantics.Role -import com.android.settingslib.RestrictedLockUtils +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.toggleableState +import androidx.compose.ui.state.ToggleableState import com.android.settingslib.spa.framework.compose.stateOf import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel @@ -38,32 +39,44 @@ import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted import com.android.settingslib.spaprivileged.model.enterprise.RestrictedMode import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl @Composable fun RestrictedSwitchPreference(model: SwitchPreferenceModel, restrictions: Restrictions) { + RestrictedSwitchPreferenceImpl(model, restrictions, ::RestrictionsProviderImpl) +} + +@Composable +internal fun RestrictedSwitchPreferenceImpl( + model: SwitchPreferenceModel, + restrictions: Restrictions, + restrictionsProviderFactory: (Context, Restrictions) -> RestrictionsProvider, +) { if (restrictions.keys.isEmpty()) { SwitchPreference(model) return } val context = LocalContext.current - val restrictionsProvider = remember { RestrictionsProvider(context, restrictions) } - val restrictedMode = restrictionsProvider.restrictedMode.observeAsState().value ?: return + val restrictionsProvider = remember(restrictions) { + restrictionsProviderFactory(context, restrictions) + } + val restrictedMode = restrictionsProvider.restrictedModeState().value val restrictedSwitchModel = remember(restrictedMode) { RestrictedSwitchPreferenceModel(context, model, restrictedMode) } - Box(remember { restrictedSwitchModel.getModifier() }) { + restrictedSwitchModel.RestrictionWrapper { SwitchPreference(restrictedSwitchModel) } } -object RestrictedSwitchPreference { +internal object RestrictedSwitchPreference { fun getSummary( context: Context, restrictedMode: RestrictedMode?, - noRestrictedSummary: State<String>, + summaryIfNoRestricted: State<String>, checked: State<Boolean?>, ): State<String> = when (restrictedMode) { - is NoRestricted -> noRestrictedSummary + is NoRestricted -> summaryIfNoRestricted is BaseUserRestricted -> stateOf(context.getString(R.string.disabled)) is BlockedByAdmin -> derivedStateOf { restrictedMode.getSummary(checked.value) } null -> stateOf(context.getString(R.string.summary_placeholder)) @@ -71,43 +84,64 @@ object RestrictedSwitchPreference { } private class RestrictedSwitchPreferenceModel( - private val context: Context, + context: Context, model: SwitchPreferenceModel, - private val restrictedMode: RestrictedMode, + private val restrictedMode: RestrictedMode?, ) : SwitchPreferenceModel { override val title = model.title override val summary = RestrictedSwitchPreference.getSummary( context = context, restrictedMode = restrictedMode, - noRestrictedSummary = model.summary, + summaryIfNoRestricted = model.summary, checked = model.checked, ) override val checked = when (restrictedMode) { + null -> stateOf(null) is NoRestricted -> model.checked is BaseUserRestricted -> stateOf(false) is BlockedByAdmin -> model.checked } override val changeable = when (restrictedMode) { + null -> stateOf(false) is NoRestricted -> model.changeable is BaseUserRestricted -> stateOf(false) is BlockedByAdmin -> stateOf(false) } override val onCheckedChange = when (restrictedMode) { + null -> null is NoRestricted -> model.onCheckedChange - is BaseUserRestricted -> null + // Need to pass a non null onCheckedChange to enable semantics ToggleableState, although + // since changeable is false this will not be called. + is BaseUserRestricted -> model.onCheckedChange + // Pass null since semantics ToggleableState is provided in RestrictionWrapper. is BlockedByAdmin -> null } - fun getModifier(): Modifier = when (restrictedMode) { - is BlockedByAdmin -> Modifier.clickable(role = Role.Switch) { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent( - context, restrictedMode.enforcedAdmin - ) + @Composable + fun RestrictionWrapper(content: @Composable () -> Unit) { + if (restrictedMode !is BlockedByAdmin) { + content() + return } - else -> Modifier + Box( + Modifier + .clickable( + role = Role.Switch, + onClick = { restrictedMode.sendShowAdminSupportDetailsIntent() }, + ) + .semantics { + this.toggleableState = ToggleableState(checked.value) + }, + ) { content() } + } + + private fun ToggleableState(value: Boolean?) = when (value) { + true -> ToggleableState.On + false -> ToggleableState.Off + null -> ToggleableState.Indeterminate } } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt new file mode 100644 index 000000000000..8c1421a66564 --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spaprivileged.template.scaffold + +import android.content.Context +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext +import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope +import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted +import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl + +@Composable +fun MoreOptionsScope.RestrictedMenuItem( + text: String, + restrictions: Restrictions, + onClick: () -> Unit, +) { + RestrictedMenuItemImpl(text, restrictions, onClick, ::RestrictionsProviderImpl) +} + +@Composable +internal fun MoreOptionsScope.RestrictedMenuItemImpl( + text: String, + restrictions: Restrictions, + onClick: () -> Unit, + restrictionsProviderFactory: (Context, Restrictions) -> RestrictionsProvider, +) { + val context = LocalContext.current + val restrictionsProvider = remember(restrictions) { + restrictionsProviderFactory(context, restrictions) + } + val restrictedMode = restrictionsProvider.restrictedModeState().value + MenuItem(text = text, enabled = restrictedMode !is BaseUserRestricted) { + when (restrictedMode) { + is BlockedByAdmin -> restrictedMode.sendShowAdminSupportDetailsIntent() + else -> onClick() + } + } +} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt new file mode 100644 index 000000000000..7f57025c5fe5 --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spaprivileged.template.preference + +import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.isOff +import androidx.compose.ui.test.isOn +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel +import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted +import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions +import com.android.settingslib.spaprivileged.tests.testutils.FakeBlockedByAdmin +import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsProvider +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class RestrictedSwitchPreferenceTest { + @get:Rule + val composeTestRule = createComposeRule() + + private val fakeBlockedByAdmin = FakeBlockedByAdmin() + + private val fakeRestrictionsProvider = FakeRestrictionsProvider() + + private val switchPreferenceModel = object : SwitchPreferenceModel { + override val title = TITLE + override val checked = mutableStateOf(true) + override val onCheckedChange: (Boolean) -> Unit = { checked.value = it } + } + + @Test + fun whenRestrictionsKeysIsEmpty_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNode(isOn()).assertIsDisplayed() + } + + @Test + fun whenRestrictionsKeysIsEmpty_toggleable() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenNoRestricted_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNode(isOn()).assertIsDisplayed() + } + + @Test + fun whenNoRestricted_toggleable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenBaseUserRestricted_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsNotEnabled() + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenBaseUserRestricted_notToggleable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenBlockedByAdmin_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNodeWithText(FakeBlockedByAdmin.SUMMARY).assertIsDisplayed() + composeTestRule.onNode(isOn()).assertIsDisplayed() + } + + @Test + fun whenBlockedByAdmin_click() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(fakeBlockedByAdmin.sendShowAdminSupportDetailsIntentIsCalled).isTrue() + } + + private fun setContent(restrictions: Restrictions) { + composeTestRule.setContent { + RestrictedSwitchPreferenceImpl(switchPreferenceModel, restrictions) { _, _ -> + fakeRestrictionsProvider + } + } + } + + private companion object { + const val TITLE = "Title" + const val USER_ID = 0 + const val RESTRICTION_KEY = "restriction_key" + } +} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt new file mode 100644 index 000000000000..983284cbabb7 --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spaprivileged.template.scaffold + +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope +import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted +import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions +import com.android.settingslib.spaprivileged.tests.testutils.FakeBlockedByAdmin +import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsProvider +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class RestrictedMenuItemTest { + @get:Rule + val composeTestRule = createComposeRule() + + private val fakeBlockedByAdmin = FakeBlockedByAdmin() + + private val fakeRestrictionsProvider = FakeRestrictionsProvider() + + private var menuItemOnClickIsCalled = false + + @Test + fun whenRestrictionsKeysIsEmpty_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenRestrictionsKeysIsEmpty_clickable() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(menuItemOnClickIsCalled).isTrue() + } + + @Test + fun whenNoRestricted_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenNoRestricted_clickable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(menuItemOnClickIsCalled).isTrue() + } + + @Test + fun whenBaseUserRestricted_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsNotEnabled() + } + + @Test + fun whenBaseUserRestricted_notClickable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(menuItemOnClickIsCalled).isFalse() + } + + @Test + fun whenBlockedByAdmin_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenBlockedByAdmin_onClick_showAdminSupportDetails() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(fakeBlockedByAdmin.sendShowAdminSupportDetailsIntentIsCalled).isTrue() + assertThat(menuItemOnClickIsCalled).isFalse() + } + + private fun setContent(restrictions: Restrictions) { + val fakeMoreOptionsScope = object : MoreOptionsScope { + override fun dismiss() {} + } + composeTestRule.setContent { + fakeMoreOptionsScope.RestrictedMenuItemImpl( + text = TEXT, + restrictions = restrictions, + onClick = { menuItemOnClickIsCalled = true }, + restrictionsProviderFactory = { _, _ -> fakeRestrictionsProvider }, + ) + } + } + + private companion object { + const val TEXT = "Text" + const val USER_ID = 0 + const val RESTRICTION_KEY = "restriction_key" + } +} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt new file mode 100644 index 000000000000..93fa17d1eeca --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spaprivileged.tests.testutils + +import androidx.compose.runtime.Composable +import com.android.settingslib.spa.framework.compose.stateOf +import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin +import com.android.settingslib.spaprivileged.model.enterprise.RestrictedMode +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider + +class FakeBlockedByAdmin : BlockedByAdmin { + var sendShowAdminSupportDetailsIntentIsCalled = false + + override fun getSummary(checked: Boolean?) = SUMMARY + + override fun sendShowAdminSupportDetailsIntent() { + sendShowAdminSupportDetailsIntentIsCalled = true + } + + companion object { + const val SUMMARY = "Blocked by admin" + } +} + +class FakeRestrictionsProvider : RestrictionsProvider { + var restrictedMode: RestrictedMode? = null + + @Composable + override fun restrictedModeState() = stateOf(restrictedMode) +} diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 2e0155b86e7f..caaa88d6aea8 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1105,6 +1105,8 @@ <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> left until full</string> <!-- [CHAR_LIMIT=80] Label for battery level chart when charge been limited --> <string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Charging is paused</string> + <!-- [CHAR_LIMIT=80] Label for battery charging future pause --> + <string name="power_charging_future_paused"><xliff:g id="level">%1$s</xliff:g> - Charging to <xliff:g id="dock_defender_threshold">%2$s</xliff:g></string> <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed --> <string name="battery_info_status_unknown">Unknown</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index 65c94cec6009..ca5f57d3d697 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -1598,6 +1598,11 @@ public class ApplicationsState { */ public boolean isHomeApp; + /** + * Whether or not it's a cloned app . + */ + public boolean isCloned; + public String getNormalizedLabel() { if (normalizedLabel != null) { return normalizedLabel; @@ -1637,7 +1642,12 @@ public class ApplicationsState { ThreadUtils.postOnBackgroundThread( () -> this.ensureLabelDescriptionLocked(context)); } - this.showInPersonalTab = shouldShowInPersonalTab(context, info.uid); + UserManager um = UserManager.get(context); + this.showInPersonalTab = shouldShowInPersonalTab(um, info.uid); + UserInfo userInfo = um.getUserInfo(UserHandle.getUserId(info.uid)); + if (userInfo != null) { + this.isCloned = userInfo.isCloneProfile(); + } } /** @@ -1645,8 +1655,7 @@ public class ApplicationsState { * {@link UserProperties#SHOW_IN_SETTINGS_WITH_PARENT} set. */ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - boolean shouldShowInPersonalTab(Context context, int uid) { - UserManager userManager = UserManager.get(context); + boolean shouldShowInPersonalTab(UserManager userManager, int uid) { int userId = UserHandle.getUserId(uid); // Regardless of apk version, if the app belongs to the current user then return true. diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 9583a59148fc..b929f8c03905 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -77,9 +77,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private final LocalBluetoothProfileManager mProfileManager; private final Object mProfileLock = new Object(); BluetoothDevice mDevice; - private int mDeviceSide; - private int mDeviceMode; - private long mHiSyncId; + private HearingAidInfo mHearingAidInfo; private int mGroupId; // Need this since there is no method for getting RSSI @@ -160,7 +158,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> mProfileManager = profileManager; mDevice = device; fillData(); - mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; mGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; initDrawableCache(); mUnpairing = false; @@ -339,32 +336,34 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> connectDevice(); } - public int getDeviceSide() { - return mDeviceSide; - } - - public void setDeviceSide(int side) { - mDeviceSide = side; + public HearingAidInfo getHearingAidInfo() { + return mHearingAidInfo; } - public int getDeviceMode() { - return mDeviceMode; + public void setHearingAidInfo(HearingAidInfo hearingAidInfo) { + mHearingAidInfo = hearingAidInfo; } - public void setDeviceMode(int mode) { - mDeviceMode = mode; + /** + * @return {@code true} if {@code cachedBluetoothDevice} is hearing aid device + */ + public boolean isHearingAidDevice() { + return mHearingAidInfo != null; } - public long getHiSyncId() { - return mHiSyncId; + public int getDeviceSide() { + return mHearingAidInfo != null + ? mHearingAidInfo.getSide() : HearingAidInfo.DeviceSide.SIDE_INVALID; } - public void setHiSyncId(long id) { - mHiSyncId = id; + public int getDeviceMode() { + return mHearingAidInfo != null + ? mHearingAidInfo.getMode() : HearingAidInfo.DeviceMode.MODE_INVALID; } - public boolean isHearingAidDevice() { - return mHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID; + public long getHiSyncId() { + return mHearingAidInfo != null + ? mHearingAidInfo.getHiSyncId() : BluetoothHearingAid.HI_SYNC_ID_INVALID; } /** @@ -784,8 +783,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> ParcelUuid[] localUuids = new ParcelUuid[uuidsList.size()]; uuidsList.toArray(localUuids); - if (localUuids == null) return false; - /* * Now we know if the device supports PBAP, update permissions... */ @@ -1173,9 +1170,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> if (subDevice != null && subDevice.isConnected()) { stringRes = R.string.bluetooth_hearing_aid_left_and_right_active; } else { - if (mDeviceSide == HearingAidProfile.DeviceSide.SIDE_LEFT) { + int deviceSide = getDeviceSide(); + if (deviceSide == HearingAidInfo.DeviceSide.SIDE_LEFT) { stringRes = R.string.bluetooth_hearing_aid_left_active; - } else if (mDeviceSide == HearingAidProfile.DeviceSide.SIDE_RIGHT) { + } else if (deviceSide == HearingAidInfo.DeviceSide.SIDE_RIGHT) { stringRes = R.string.bluetooth_hearing_aid_right_active; } else { stringRes = R.string.bluetooth_active_no_battery_level; @@ -1371,15 +1369,41 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } /** - * @return {@code true} if {@code cachedBluetoothDevice} is Hearing Aid device + * @return {@code true} if {@code cachedBluetoothDevice} is ASHA hearing aid device */ - public boolean isConnectedHearingAidDevice() { + public boolean isConnectedAshaHearingAidDevice() { HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile(); return hearingAidProfile != null && hearingAidProfile.getConnectionStatus(mDevice) == BluetoothProfile.STATE_CONNECTED; } /** + * @return {@code true} if {@code cachedBluetoothDevice} is HAP device + */ + public boolean isConnectedHapClientDevice() { + HapClientProfile hapClientProfile = mProfileManager.getHapClientProfile(); + return hapClientProfile != null && hapClientProfile.getConnectionStatus(mDevice) + == BluetoothProfile.STATE_CONNECTED; + } + + /** + * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio hearing aid device + */ + public boolean isConnectedLeAudioHearingAidDevice() { + return isConnectedHapClientDevice() && isConnectedLeAudioDevice(); + } + + /** + * @return {@code true} if {@code cachedBluetoothDevice} is hearing aid device + * + * The device may be an ASHA hearing aid that supports {@link HearingAidProfile} or a LeAudio + * hearing aid that supports {@link HapClientProfile} and {@link LeAudioProfile}. + */ + public boolean isConnectedHearingAidDevice() { + return isConnectedAshaHearingAidDevice() || isConnectedLeAudioHearingAidDevice(); + } + + /** * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio device */ public boolean isConnectedLeAudioDevice() { @@ -1407,17 +1431,17 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> BluetoothDevice tmpDevice = mDevice; final short tmpRssi = mRssi; final boolean tmpJustDiscovered = mJustDiscovered; - final int tmpDeviceSide = mDeviceSide; + final HearingAidInfo tmpHearingAidInfo = mHearingAidInfo; // Set main device from sub device mDevice = mSubDevice.mDevice; mRssi = mSubDevice.mRssi; mJustDiscovered = mSubDevice.mJustDiscovered; - mDeviceSide = mSubDevice.mDeviceSide; + mHearingAidInfo = mSubDevice.mHearingAidInfo; // Set sub device from backup mSubDevice.mDevice = tmpDevice; mSubDevice.mRssi = tmpRssi; mSubDevice.mJustDiscovered = tmpJustDiscovered; - mSubDevice.mDeviceSide = tmpDeviceSide; + mSubDevice.mHearingAidInfo = tmpHearingAidInfo; fetchActiveDevices(); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java index cf4e1ee99f92..ebfec0aee1b7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java @@ -27,7 +27,7 @@ import java.util.List; import java.util.Set; /** - * HearingAidDeviceManager manages the set of remote HearingAid Bluetooth devices. + * HearingAidDeviceManager manages the set of remote HearingAid(ASHA) Bluetooth devices. */ public class HearingAidDeviceManager { private static final String TAG = "HearingAidDeviceManager"; @@ -44,12 +44,12 @@ public class HearingAidDeviceManager { void initHearingAidDeviceIfNeeded(CachedBluetoothDevice newDevice) { long hiSyncId = getHiSyncId(newDevice.getDevice()); if (isValidHiSyncId(hiSyncId)) { - // Once hiSyncId is valid, assign hiSyncId - newDevice.setHiSyncId(hiSyncId); - final int side = getDeviceSide(newDevice.getDevice()); - final int mode = getDeviceMode(newDevice.getDevice()); - newDevice.setDeviceSide(side); - newDevice.setDeviceMode(mode); + // Once hiSyncId is valid, assign hearing aid info + final HearingAidInfo.Builder infoBuilder = new HearingAidInfo.Builder() + .setAshaDeviceSide(getDeviceSide(newDevice.getDevice())) + .setAshaDeviceMode(getDeviceMode(newDevice.getDevice())) + .setHiSyncId(hiSyncId); + newDevice.setHearingAidInfo(infoBuilder.build()); } } @@ -123,12 +123,14 @@ public class HearingAidDeviceManager { final long newHiSyncId = getHiSyncId(cachedDevice.getDevice()); // Do nothing if there is no HiSyncId on Bluetooth device if (isValidHiSyncId(newHiSyncId)) { - cachedDevice.setHiSyncId(newHiSyncId); + // Once hiSyncId is valid, assign hearing aid info + final HearingAidInfo.Builder infoBuilder = new HearingAidInfo.Builder() + .setAshaDeviceSide(getDeviceSide(cachedDevice.getDevice())) + .setAshaDeviceMode(getDeviceMode(cachedDevice.getDevice())) + .setHiSyncId(newHiSyncId); + cachedDevice.setHearingAidInfo(infoBuilder.build()); + newSyncIdSet.add(newHiSyncId); - final int side = getDeviceSide(cachedDevice.getDevice()); - final int mode = getDeviceMode(cachedDevice.getDevice()); - cachedDevice.setDeviceSide(side); - cachedDevice.setDeviceMode(mode); } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidInfo.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidInfo.java new file mode 100644 index 000000000000..ef08c924b844 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidInfo.java @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth; + +import android.annotation.IntDef; +import android.bluetooth.BluetoothHearingAid; +import android.bluetooth.BluetoothLeAudio; +import android.util.SparseIntArray; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** Hearing aids information and constants that shared within hearing aids related profiles */ +public class HearingAidInfo { + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + DeviceSide.SIDE_INVALID, + DeviceSide.SIDE_LEFT, + DeviceSide.SIDE_RIGHT, + DeviceSide.SIDE_LEFT_AND_RIGHT, + }) + + /** Side definition for hearing aids. */ + public @interface DeviceSide { + int SIDE_INVALID = -1; + int SIDE_LEFT = 0; + int SIDE_RIGHT = 1; + int SIDE_LEFT_AND_RIGHT = 2; + } + + @Retention(java.lang.annotation.RetentionPolicy.SOURCE) + @IntDef({ + DeviceMode.MODE_INVALID, + DeviceMode.MODE_MONAURAL, + DeviceMode.MODE_BINAURAL, + DeviceMode.MODE_BANDED, + }) + + /** Mode definition for hearing aids. */ + public @interface DeviceMode { + int MODE_INVALID = -1; + int MODE_MONAURAL = 0; + int MODE_BINAURAL = 1; + int MODE_BANDED = 2; + } + + private final int mSide; + private final int mMode; + private final long mHiSyncId; + + private HearingAidInfo(int side, int mode, long hiSyncId) { + mSide = side; + mMode = mode; + mHiSyncId = hiSyncId; + } + + @DeviceSide + public int getSide() { + return mSide; + } + + @DeviceMode + public int getMode() { + return mMode; + } + + public long getHiSyncId() { + return mHiSyncId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof HearingAidInfo)) { + return false; + } + HearingAidInfo that = (HearingAidInfo) o; + return mSide == that.mSide && mMode == that.mMode && mHiSyncId == that.mHiSyncId; + } + + @Override + public int hashCode() { + return Objects.hash(mSide, mMode, mHiSyncId); + } + + @Override + public String toString() { + return "HearingAidInfo{" + + "mSide=" + mSide + + ", mMode=" + mMode + + ", mHiSyncId=" + mHiSyncId + + '}'; + } + + @DeviceSide + private static int convertAshaDeviceSideToInternalSide(int ashaDeviceSide) { + return ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.get( + ashaDeviceSide, DeviceSide.SIDE_INVALID); + } + + @DeviceMode + private static int convertAshaDeviceModeToInternalMode(int ashaDeviceMode) { + return ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.get( + ashaDeviceMode, DeviceMode.MODE_INVALID); + } + + @DeviceSide + private static int convertLeAudioLocationToInternalSide(int leAudioLocation) { + boolean isLeft = (leAudioLocation & LE_AUDIO_LOCATION_LEFT) != 0; + boolean isRight = (leAudioLocation & LE_AUDIO_LOCATION_RIGHT) != 0; + if (isLeft && isRight) { + return DeviceSide.SIDE_LEFT_AND_RIGHT; + } else if (isLeft) { + return DeviceSide.SIDE_LEFT; + } else if (isRight) { + return DeviceSide.SIDE_RIGHT; + } + return DeviceSide.SIDE_INVALID; + } + + @DeviceMode + private static int convertHapDeviceTypeToInternalMode(int hapDeviceType) { + return HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.get(hapDeviceType, DeviceMode.MODE_INVALID); + } + + /** Builder class for constructing {@link HearingAidInfo} objects. */ + public static final class Builder { + private int mSide = DeviceSide.SIDE_INVALID; + private int mMode = DeviceMode.MODE_INVALID; + private long mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; + + /** + * Configure the hearing device mode. + * @param ashaDeviceMode one of the hearing aid device modes defined in HearingAidProfile + * {@link HearingAidProfile.DeviceMode} + */ + public Builder setAshaDeviceMode(int ashaDeviceMode) { + mMode = convertAshaDeviceModeToInternalMode(ashaDeviceMode); + return this; + } + + /** + * Configure the hearing device mode. + * @param hapDeviceType one of the hearing aid device types defined in HapClientProfile + * {@link HapClientProfile.HearingAidType} + */ + public Builder setHapDeviceType(int hapDeviceType) { + mMode = convertHapDeviceTypeToInternalMode(hapDeviceType); + return this; + } + + /** + * Configure the hearing device side. + * @param ashaDeviceSide one of the hearing aid device sides defined in HearingAidProfile + * {@link HearingAidProfile.DeviceSide} + */ + public Builder setAshaDeviceSide(int ashaDeviceSide) { + mSide = convertAshaDeviceSideToInternalSide(ashaDeviceSide); + return this; + } + + /** + * Configure the hearing device side. + * @param leAudioLocation one of the audio location defined in BluetoothLeAudio + * {@link BluetoothLeAudio.AudioLocation} + */ + public Builder setLeAudioLocation(int leAudioLocation) { + mSide = convertLeAudioLocationToInternalSide(leAudioLocation); + return this; + } + + /** + * Configure the hearing aid hiSyncId. + * @param hiSyncId the ASHA hearing aid id + */ + public Builder setHiSyncId(long hiSyncId) { + mHiSyncId = hiSyncId; + return this; + } + + /** Build the configured {@link HearingAidInfo} */ + public HearingAidInfo build() { + return new HearingAidInfo(mSide, mMode, mHiSyncId); + } + } + + private static final int LE_AUDIO_LOCATION_LEFT = + BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT + | BluetoothLeAudio.AUDIO_LOCATION_BACK_LEFT + | BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT_OF_CENTER + | BluetoothLeAudio.AUDIO_LOCATION_SIDE_LEFT + | BluetoothLeAudio.AUDIO_LOCATION_TOP_FRONT_LEFT + | BluetoothLeAudio.AUDIO_LOCATION_TOP_BACK_LEFT + | BluetoothLeAudio.AUDIO_LOCATION_TOP_SIDE_LEFT + | BluetoothLeAudio.AUDIO_LOCATION_BOTTOM_FRONT_LEFT + | BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT_WIDE + | BluetoothLeAudio.AUDIO_LOCATION_LEFT_SURROUND; + + private static final int LE_AUDIO_LOCATION_RIGHT = + BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT + | BluetoothLeAudio.AUDIO_LOCATION_BACK_RIGHT + | BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT_OF_CENTER + | BluetoothLeAudio.AUDIO_LOCATION_SIDE_RIGHT + | BluetoothLeAudio.AUDIO_LOCATION_TOP_FRONT_RIGHT + | BluetoothLeAudio.AUDIO_LOCATION_TOP_BACK_RIGHT + | BluetoothLeAudio.AUDIO_LOCATION_TOP_SIDE_RIGHT + | BluetoothLeAudio.AUDIO_LOCATION_BOTTOM_FRONT_RIGHT + | BluetoothLeAudio.AUDIO_LOCATION_FRONT_RIGHT_WIDE + | BluetoothLeAudio.AUDIO_LOCATION_RIGHT_SURROUND; + + private static final SparseIntArray ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING; + private static final SparseIntArray ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING; + private static final SparseIntArray HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING; + + static { + ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING = new SparseIntArray(); + ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put( + HearingAidProfile.DeviceSide.SIDE_INVALID, DeviceSide.SIDE_INVALID); + ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put( + HearingAidProfile.DeviceSide.SIDE_LEFT, DeviceSide.SIDE_LEFT); + ASHA_DEVICE_SIDE_TO_INTERNAL_SIDE_MAPPING.put( + HearingAidProfile.DeviceSide.SIDE_RIGHT, DeviceSide.SIDE_RIGHT); + + ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING = new SparseIntArray(); + ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put( + HearingAidProfile.DeviceMode.MODE_INVALID, DeviceMode.MODE_INVALID); + ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put( + HearingAidProfile.DeviceMode.MODE_MONAURAL, DeviceMode.MODE_MONAURAL); + ASHA_DEVICE_MODE_TO_INTERNAL_MODE_MAPPING.put( + HearingAidProfile.DeviceMode.MODE_BINAURAL, DeviceMode.MODE_BINAURAL); + + HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING = new SparseIntArray(); + HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( + HapClientProfile.HearingAidType.TYPE_INVALID, DeviceMode.MODE_INVALID); + HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( + HapClientProfile.HearingAidType.TYPE_BINAURAL, DeviceMode.MODE_BINAURAL); + HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( + HapClientProfile.HearingAidType.TYPE_MONAURAL, DeviceMode.MODE_MONAURAL); + HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( + HapClientProfile.HearingAidType.TYPE_BANDED, DeviceMode.MODE_BANDED); + HAP_DEVICE_TYPE_TO_INTERNAL_MODE_MAPPING.put( + HapClientProfile.HearingAidType.TYPE_RFU, DeviceMode.MODE_INVALID); + + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java index fb861da0a7f0..a3c2e70c7da4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java @@ -21,6 +21,7 @@ import android.bluetooth.BluetoothA2dpSink; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadsetClient; import android.bluetooth.BluetoothHearingAid; @@ -103,6 +104,7 @@ public class LocalBluetoothProfileManager { private PbapClientProfile mPbapClientProfile; private PbapServerProfile mPbapProfile; private HearingAidProfile mHearingAidProfile; + private HapClientProfile mHapClientProfile; private CsipSetCoordinatorProfile mCsipSetCoordinatorProfile; private LeAudioProfile mLeAudioProfile; private LocalBluetoothLeBroadcast mLeAudioBroadcast; @@ -189,6 +191,12 @@ public class LocalBluetoothProfileManager { addProfile(mHearingAidProfile, HearingAidProfile.NAME, BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); } + if (mHapClientProfile == null && supportedList.contains(BluetoothProfile.HAP_CLIENT)) { + if (DEBUG) Log.d(TAG, "Adding local HAP_CLIENT profile"); + mHapClientProfile = new HapClientProfile(mContext, mDeviceManager, this); + addProfile(mHapClientProfile, HapClientProfile.NAME, + BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); + } if (mHidProfile == null && supportedList.contains(BluetoothProfile.HID_HOST)) { if (DEBUG) Log.d(TAG, "Adding local HID_HOST profile"); mHidProfile = new HidProfile(mContext, mDeviceManager, this); @@ -337,25 +345,44 @@ public class LocalBluetoothProfileManager { Log.i(TAG, "Failed to connect " + mProfile + " device"); } - if (getHearingAidProfile() != null && - mProfile instanceof HearingAidProfile && - (newState == BluetoothProfile.STATE_CONNECTED)) { - final int side = getHearingAidProfile().getDeviceSide(cachedDevice.getDevice()); - final int mode = getHearingAidProfile().getDeviceMode(cachedDevice.getDevice()); - cachedDevice.setDeviceSide(side); - cachedDevice.setDeviceMode(mode); + if (getHearingAidProfile() != null + && mProfile instanceof HearingAidProfile + && (newState == BluetoothProfile.STATE_CONNECTED)) { // Check if the HiSyncID has being initialized if (cachedDevice.getHiSyncId() == BluetoothHearingAid.HI_SYNC_ID_INVALID) { long newHiSyncId = getHearingAidProfile().getHiSyncId(cachedDevice.getDevice()); if (newHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID) { - cachedDevice.setHiSyncId(newHiSyncId); + final BluetoothDevice device = cachedDevice.getDevice(); + final HearingAidInfo.Builder infoBuilder = new HearingAidInfo.Builder() + .setAshaDeviceSide(getHearingAidProfile().getDeviceSide(device)) + .setAshaDeviceMode(getHearingAidProfile().getDeviceMode(device)) + .setHiSyncId(newHiSyncId); + cachedDevice.setHearingAidInfo(infoBuilder.build()); } } - HearingAidStatsLogUtils.logHearingAidInfo(cachedDevice); } + final boolean isHapClientProfile = getHapClientProfile() != null + && mProfile instanceof HapClientProfile; + final boolean isLeAudioProfile = getLeAudioProfile() != null + && mProfile instanceof LeAudioProfile; + final boolean isHapClientOrLeAudioProfile = isHapClientProfile || isLeAudioProfile; + if (isHapClientOrLeAudioProfile && newState == BluetoothProfile.STATE_CONNECTED) { + + // Checks if both profiles are connected to the device. Hearing aid info need + // to be retrieved from these profiles separately. + if (cachedDevice.isConnectedLeAudioHearingAidDevice()) { + final BluetoothDevice device = cachedDevice.getDevice(); + final HearingAidInfo.Builder infoBuilder = new HearingAidInfo.Builder() + .setLeAudioLocation(getLeAudioProfile().getAudioLocation(device)) + .setHapDeviceType(getHapClientProfile().getHearingAidType(device)); + cachedDevice.setHearingAidInfo(infoBuilder.build()); + HearingAidStatsLogUtils.logHearingAidInfo(cachedDevice); + } + } + if (getCsipSetCoordinatorProfile() != null && mProfile instanceof CsipSetCoordinatorProfile && newState == BluetoothProfile.STATE_CONNECTED) { @@ -524,6 +551,10 @@ public class LocalBluetoothProfileManager { return mHearingAidProfile; } + public HapClientProfile getHapClientProfile() { + return mHapClientProfile; + } + public LeAudioProfile getLeAudioProfile() { return mLeAudioProfile; } @@ -675,6 +706,11 @@ public class LocalBluetoothProfileManager { removedProfiles.remove(mHearingAidProfile); } + if (mHapClientProfile != null && ArrayUtils.contains(uuids, BluetoothUuid.HAS)) { + profiles.add(mHapClientProfile); + removedProfiles.remove(mHapClientProfile); + } + if (mSapProfile != null && ArrayUtils.contains(uuids, BluetoothUuid.SAP)) { profiles.add(mSapProfile); removedProfiles.remove(mSapProfile); diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java index df6929e114ee..b3a52b9ec788 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java @@ -16,6 +16,7 @@ package com.android.settingslib.media; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHearingAid; import android.media.MediaRoute2Info; import com.android.settingslib.bluetooth.CachedBluetoothDevice; @@ -32,7 +33,9 @@ public class MediaDeviceUtils { */ public static String getId(CachedBluetoothDevice cachedDevice) { if (cachedDevice.isHearingAidDevice()) { - return Long.toString(cachedDevice.getHiSyncId()); + if (cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) { + return Long.toString(cachedDevice.getHiSyncId()); + } } return cachedDevice.getAddress(); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java index 39875f7950e4..96e64ea1de71 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java @@ -755,28 +755,30 @@ public class ApplicationsStateRoboTest { @Test public void shouldShowInPersonalTab_forCurrentUser_returnsTrue() { + UserManager um = RuntimeEnvironment.application.getSystemService(UserManager.class); ApplicationInfo appInfo = createApplicationInfo(PKG_1); AppEntry primaryUserApp = createAppEntry(appInfo, 1); - assertThat(primaryUserApp.shouldShowInPersonalTab(mContext, appInfo.uid)).isTrue(); + assertThat(primaryUserApp.shouldShowInPersonalTab(um, appInfo.uid)).isTrue(); } @Test public void shouldShowInPersonalTab_userProfilePreU_returnsFalse() { + UserManager um = RuntimeEnvironment.application.getSystemService(UserManager.class); ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.TIRAMISU); // Create an app (and subsequent AppEntry) in a non-primary user profile. ApplicationInfo appInfo1 = createApplicationInfo(PKG_1, PROFILE_UID_1); AppEntry nonPrimaryUserApp = createAppEntry(appInfo1, 1); - assertThat(nonPrimaryUserApp.shouldShowInPersonalTab(mContext, appInfo1.uid)).isFalse(); + assertThat(nonPrimaryUserApp.shouldShowInPersonalTab(um, appInfo1.uid)).isFalse(); } @Test public void shouldShowInPersonalTab_currentUserIsParent_returnsAsPerUserPropertyOfProfile1() { // Mark system user as parent for both profile users. - ShadowUserManager shadowUserManager = Shadow - .extract(RuntimeEnvironment.application.getSystemService(UserManager.class)); + UserManager um = RuntimeEnvironment.application.getSystemService(UserManager.class); + ShadowUserManager shadowUserManager = Shadow.extract(um); shadowUserManager.addProfile(USER_SYSTEM, PROFILE_USERID, CLONE_USER, 0); shadowUserManager.addProfile(USER_SYSTEM, PROFILE_USERID2, @@ -796,7 +798,7 @@ public class ApplicationsStateRoboTest { AppEntry nonPrimaryUserApp1 = createAppEntry(appInfo1, 1); AppEntry nonPrimaryUserApp2 = createAppEntry(appInfo2, 2); - assertThat(nonPrimaryUserApp1.shouldShowInPersonalTab(mContext, appInfo1.uid)).isTrue(); - assertThat(nonPrimaryUserApp2.shouldShowInPersonalTab(mContext, appInfo2.uid)).isFalse(); + assertThat(nonPrimaryUserApp1.shouldShowInPersonalTab(um, appInfo1.uid)).isTrue(); + assertThat(nonPrimaryUserApp2.shouldShowInPersonalTab(um, appInfo2.uid)).isFalse(); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java index 61802a87361c..f06623d0bd4a 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java @@ -327,8 +327,10 @@ public class CachedBluetoothDeviceManagerTest { when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2); - cachedDevice1.setHiSyncId(HISYNCID1); - cachedDevice2.setHiSyncId(HISYNCID1); + cachedDevice1.setHearingAidInfo( + new HearingAidInfo.Builder().setHiSyncId(HISYNCID1).build()); + cachedDevice2.setHearingAidInfo( + new HearingAidInfo.Builder().setHiSyncId(HISYNCID1).build()); cachedDevice1.setSubDevice(cachedDevice2); // Call onDeviceUnpaired for the one in mCachedDevices. diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index 79e99387b2fa..1f518ec17f55 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -74,6 +74,10 @@ public class CachedBluetoothDeviceTest { @Mock private HearingAidProfile mHearingAidProfile; @Mock + private HapClientProfile mHapClientProfile; + @Mock + private LeAudioProfile mLeAudioProfile; + @Mock private BluetoothDevice mDevice; @Mock private BluetoothDevice mSubDevice; @@ -354,7 +358,7 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for Hearing Aid and test connection state summary - mCachedDevice.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT); + mCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, left only"); @@ -399,7 +403,7 @@ public class CachedBluetoothDeviceTest { // 1. Profile: {HEARING_AID, Connected, Active, Right ear} // 2. Audio Manager: In Call updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); - mCachedDevice.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_RIGHT); + mCachedDevice.setHearingAidInfo(getRightAshaHearingAidInfo()); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); mAudioManager.setMode(AudioManager.MODE_IN_CALL); @@ -413,9 +417,9 @@ public class CachedBluetoothDeviceTest { // Arrange: // 1. Profile: {HEARING_AID, Connected, Active, Both ear} // 2. Audio Manager: In Call - mCachedDevice.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_RIGHT); + mCachedDevice.setHearingAidInfo(getRightAshaHearingAidInfo()); updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); - mSubCachedDevice.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT); + mSubCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); updateSubDeviceProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.setSubDevice(mSubCachedDevice); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); @@ -859,21 +863,21 @@ public class CachedBluetoothDeviceTest { } @Test - public void isConnectedHearingAidDevice_connected_returnTrue() { + public void isConnectedAshaHearingAidDevice_connected_returnTrue() { when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); when(mHearingAidProfile.getConnectionStatus(mDevice)). thenReturn(BluetoothProfile.STATE_CONNECTED); - assertThat(mCachedDevice.isConnectedHearingAidDevice()).isTrue(); + assertThat(mCachedDevice.isConnectedAshaHearingAidDevice()).isTrue(); } @Test - public void isConnectedHearingAidDevice_disconnected_returnFalse() { + public void isConnectedAshaHearingAidDevice_disconnected_returnFalse() { when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); when(mHearingAidProfile.getConnectionStatus(mDevice)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); - assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse(); + assertThat(mCachedDevice.isConnectedAshaHearingAidDevice()).isFalse(); } @Test @@ -891,10 +895,10 @@ public class CachedBluetoothDeviceTest { } @Test - public void isConnectedHearingAidDevice_profileIsNull_returnFalse() { + public void isConnectedAshaHearingAidDevice_profileIsNull_returnFalse() { when(mProfileManager.getHearingAidProfile()).thenReturn(null); - assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse(); + assertThat(mCachedDevice.isConnectedAshaHearingAidDevice()).isFalse(); } @Test @@ -965,10 +969,10 @@ public class CachedBluetoothDeviceTest { mCachedDevice.mRssi = RSSI_1; mCachedDevice.mJustDiscovered = JUSTDISCOVERED_1; - mCachedDevice.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT); + mCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo()); mSubCachedDevice.mRssi = RSSI_2; mSubCachedDevice.mJustDiscovered = JUSTDISCOVERED_2; - mSubCachedDevice.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_RIGHT); + mSubCachedDevice.setHearingAidInfo(getRightAshaHearingAidInfo()); mCachedDevice.setSubDevice(mSubCachedDevice); mCachedDevice.switchSubDeviceContent(); @@ -976,22 +980,20 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.mRssi).isEqualTo(RSSI_2); assertThat(mCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_2); assertThat(mCachedDevice.mDevice).isEqualTo(mSubDevice); - assertThat(mCachedDevice.getDeviceSide()).isEqualTo( - HearingAidProfile.DeviceSide.SIDE_RIGHT); + assertThat(mCachedDevice.getDeviceSide()).isEqualTo(HearingAidInfo.DeviceSide.SIDE_RIGHT); assertThat(mSubCachedDevice.mRssi).isEqualTo(RSSI_1); assertThat(mSubCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_1); assertThat(mSubCachedDevice.mDevice).isEqualTo(mDevice); - assertThat(mSubCachedDevice.getDeviceSide()).isEqualTo( - HearingAidProfile.DeviceSide.SIDE_LEFT); + assertThat(mSubCachedDevice.getDeviceSide()).isEqualTo(HearingAidInfo.DeviceSide.SIDE_LEFT); } @Test public void getConnectionSummary_profileConnectedFail_showErrorMessage() { - final A2dpProfile profle = mock(A2dpProfile.class); - mCachedDevice.onProfileStateChanged(profle, BluetoothProfile.STATE_CONNECTED); + final A2dpProfile profile = mock(A2dpProfile.class); + mCachedDevice.onProfileStateChanged(profile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.setProfileConnectedStatus(BluetoothProfile.A2DP, true); - when(profle.getConnectionStatus(mDevice)).thenReturn(BluetoothProfile.STATE_CONNECTED); + when(profile.getConnectionStatus(mDevice)).thenReturn(BluetoothProfile.STATE_CONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( mContext.getString(R.string.profile_connect_timeout_subtext)); @@ -1069,4 +1071,48 @@ public class CachedBluetoothDeviceTest { assertThat(mSubCachedDevice.mDevice).isEqualTo(mDevice); assertThat(mCachedDevice.getMemberDevice().contains(mSubCachedDevice)).isTrue(); } + + @Test + public void isConnectedHearingAidDevice_isConnectedAshaHearingAidDevice_returnTrue() { + when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + + updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + + assertThat(mCachedDevice.isConnectedHearingAidDevice()).isTrue(); + } + + @Test + public void isConnectedHearingAidDevice_isConnectedLeAudioHearingAidDevice_returnTrue() { + when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile); + when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); + + updateProfileStatus(mHapClientProfile, BluetoothProfile.STATE_CONNECTED); + updateProfileStatus(mLeAudioProfile, BluetoothProfile.STATE_CONNECTED); + + assertThat(mCachedDevice.isConnectedHearingAidDevice()).isTrue(); + } + + @Test + public void isConnectedHearingAidDevice_isNotAnyConnectedHearingAidDevice_returnFalse() { + when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile); + when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); + + updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED); + updateProfileStatus(mHapClientProfile, BluetoothProfile.STATE_DISCONNECTED); + updateProfileStatus(mLeAudioProfile, BluetoothProfile.STATE_DISCONNECTED); + + assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse(); + } + + private HearingAidInfo getLeftAshaHearingAidInfo() { + return new HearingAidInfo.Builder() + .setAshaDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT) + .build(); + } + private HearingAidInfo getRightAshaHearingAidInfo() { + return new HearingAidInfo.Builder() + .setAshaDeviceSide(HearingAidProfile.DeviceSide.SIDE_RIGHT) + .build(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java index 611b0a4a28b8..470d8e07f1f8 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java @@ -17,6 +17,7 @@ package com.android.settingslib.bluetooth; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -106,7 +107,7 @@ public class HearingAidDeviceManagerTest { * deviceSide, deviceMode. */ @Test - public void initHearingAidDeviceIfNeeded_validHiSyncId_setHearingAidInfos() { + public void initHearingAidDeviceIfNeeded_validHiSyncId_setHearingAidInfo() { when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn(HISYNCID1); when(mHearingAidProfile.getDeviceMode(mDevice1)).thenReturn( HearingAidProfile.DeviceMode.MODE_BINAURAL); @@ -118,21 +119,22 @@ public class HearingAidDeviceManagerTest { assertThat(mCachedDevice1.getHiSyncId()).isEqualTo(HISYNCID1); assertThat(mCachedDevice1.getDeviceMode()).isEqualTo( - HearingAidProfile.DeviceMode.MODE_BINAURAL); + HearingAidInfo.DeviceMode.MODE_BINAURAL); assertThat(mCachedDevice1.getDeviceSide()).isEqualTo( - HearingAidProfile.DeviceSide.SIDE_RIGHT); + HearingAidInfo.DeviceSide.SIDE_RIGHT); } /** * Test initHearingAidDeviceIfNeeded, an invalid HiSyncId will not be assigned */ @Test - public void initHearingAidDeviceIfNeeded_invalidHiSyncId_notToSetHiSyncId() { + public void initHearingAidDeviceIfNeeded_invalidHiSyncId_notToSetHearingAidInfo() { when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn( BluetoothHearingAid.HI_SYNC_ID_INVALID); + mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1); - verify(mCachedDevice1, never()).setHiSyncId(anyLong()); + verify(mCachedDevice1, never()).setHearingAidInfo(any(HearingAidInfo.class)); } /** @@ -140,9 +142,10 @@ public class HearingAidDeviceManagerTest { */ @Test public void setSubDeviceIfNeeded_sameHiSyncId_setSubDevice() { - mCachedDevice1.setHiSyncId(HISYNCID1); - mCachedDevice2.setHiSyncId(HISYNCID1); + mCachedDevice1.setHearingAidInfo(getLeftAshaHearingAidInfo(HISYNCID1)); + mCachedDevice2.setHearingAidInfo(getRightAshaHearingAidInfo(HISYNCID1)); mCachedDeviceManager.mCachedDevices.add(mCachedDevice1); + mHearingAidDeviceManager.setSubDeviceIfNeeded(mCachedDevice2); assertThat(mCachedDevice1.getSubDevice()).isEqualTo(mCachedDevice2); @@ -153,9 +156,10 @@ public class HearingAidDeviceManagerTest { */ @Test public void setSubDeviceIfNeeded_differentHiSyncId_notSetSubDevice() { - mCachedDevice1.setHiSyncId(HISYNCID1); - mCachedDevice2.setHiSyncId(HISYNCID2); + mCachedDevice1.setHearingAidInfo(getLeftAshaHearingAidInfo(HISYNCID1)); + mCachedDevice2.setHearingAidInfo(getRightAshaHearingAidInfo(HISYNCID2)); mCachedDeviceManager.mCachedDevices.add(mCachedDevice1); + mHearingAidDeviceManager.setSubDeviceIfNeeded(mCachedDevice2); assertThat(mCachedDevice1.getSubDevice()).isNull(); @@ -276,9 +280,9 @@ public class HearingAidDeviceManagerTest { assertThat(mCachedDevice1.getHiSyncId()).isEqualTo(HISYNCID1); assertThat(mCachedDevice1.getDeviceMode()).isEqualTo( - HearingAidProfile.DeviceMode.MODE_BINAURAL); + HearingAidInfo.DeviceMode.MODE_BINAURAL); assertThat(mCachedDevice1.getDeviceSide()).isEqualTo( - HearingAidProfile.DeviceSide.SIDE_RIGHT); + HearingAidInfo.DeviceSide.SIDE_RIGHT); verify(mHearingAidDeviceManager).onHiSyncIdChanged(HISYNCID1); } @@ -389,11 +393,9 @@ public class HearingAidDeviceManagerTest { @Test public void onProfileConnectionStateChanged_disconnected_mainDevice_subDeviceConnected_switch() { - when(mCachedDevice1.getHiSyncId()).thenReturn(HISYNCID1); - mCachedDevice1.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT); - when(mCachedDevice2.getHiSyncId()).thenReturn(HISYNCID1); + mCachedDevice1.setHearingAidInfo(getLeftAshaHearingAidInfo(HISYNCID1)); + mCachedDevice2.setHearingAidInfo(getRightAshaHearingAidInfo(HISYNCID1)); when(mCachedDevice2.isConnected()).thenReturn(true); - mCachedDevice2.setDeviceSide(HearingAidProfile.DeviceSide.SIDE_RIGHT); mCachedDeviceManager.mCachedDevices.add(mCachedDevice1); mCachedDevice1.setSubDevice(mCachedDevice2); @@ -404,10 +406,8 @@ public class HearingAidDeviceManagerTest { assertThat(mCachedDevice1.mDevice).isEqualTo(mDevice2); assertThat(mCachedDevice2.mDevice).isEqualTo(mDevice1); - assertThat(mCachedDevice1.getDeviceSide()).isEqualTo( - HearingAidProfile.DeviceSide.SIDE_RIGHT); - assertThat(mCachedDevice2.getDeviceSide()).isEqualTo( - HearingAidProfile.DeviceSide.SIDE_LEFT); + assertThat(mCachedDevice1.getDeviceSide()).isEqualTo(HearingAidInfo.DeviceSide.SIDE_RIGHT); + assertThat(mCachedDevice2.getDeviceSide()).isEqualTo(HearingAidInfo.DeviceSide.SIDE_LEFT); verify(mCachedDevice1).refresh(); } @@ -455,4 +455,18 @@ public class HearingAidDeviceManagerTest { assertThat(mHearingAidDeviceManager.findMainDevice(mCachedDevice2)). isEqualTo(mCachedDevice1); } + + private HearingAidInfo getLeftAshaHearingAidInfo(long hiSyncId) { + return new HearingAidInfo.Builder() + .setAshaDeviceSide(HearingAidInfo.DeviceSide.SIDE_LEFT) + .setHiSyncId(hiSyncId) + .build(); + } + + private HearingAidInfo getRightAshaHearingAidInfo(long hiSyncId) { + return new HearingAidInfo.Builder() + .setAshaDeviceSide(HearingAidInfo.DeviceSide.SIDE_RIGHT) + .setHiSyncId(hiSyncId) + .build(); + } } diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 98af15a85238..267c196addec 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -53,6 +53,7 @@ public class SecureSettings { Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, + Settings.Secure.CONTRAST_LEVEL, Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 80af69c32b05..def9c197a221 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -86,6 +86,7 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.CONTRAST_LEVEL, new InclusiveFloatRangeValidator(-1f, 1f)); VALIDATORS.put( Secure.ACCESSIBILITY_CAPTIONING_PRESET, new DiscreteValueValidator(new String[] {"-1", "0", "1", "2", "3", "4"})); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 4e2bce226d6c..17078c4c81f2 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1762,6 +1762,9 @@ class SettingsProtoDumpUtil { Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, SecureSettingsProto.Accessibility.HIGH_TEXT_CONTRAST_ENABLED); dumpSetting(s, p, + Settings.Secure.CONTRAST_LEVEL, + SecureSettingsProto.Accessibility.CONTRAST_LEVEL); + dumpSetting(s, p, Settings.Secure.FONT_WEIGHT_ADJUSTMENT, SecureSettingsProto.FONT_WEIGHT_ADJUSTMENT); dumpSetting(s, p, diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 5c70edafc91a..7c3948a19792 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -168,15 +168,25 @@ java_library { } android_library { - name: "SystemUI-tests-base", + name: "SystemUI-tests", manifest: "tests/AndroidManifest-base.xml", - + additional_manifests: ["tests/AndroidManifest.xml"], + resource_dirs: [ "tests/res", "res-product", "res-keyguard", "res", ], + srcs: [ + "tests/src/**/*.kt", + "tests/src/**/*.java", + "src/**/*.kt", + "src/**/*.java", + "src/**/I*.aidl", + ":ReleaseJavaFiles", + ":SystemUI-tests-utils", + ], static_libs: [ "WifiTrackerLib", "SystemUIAnimationLib", @@ -215,6 +225,9 @@ android_library { "metrics-helper-lib", "hamcrest-library", "androidx.test.rules", + "androidx.test.uiautomator_uiautomator", + "mockito-target-extended-minus-junit4", + "androidx.test.ext.junit", "testables", "truth-prebuilt", "monet", @@ -229,36 +242,6 @@ android_library { "android.test.base", "android.test.mock", ], -} - -// Device tests only -android_library { - name: "SystemUI-tests", - manifest: "tests/AndroidManifest.xml", - additional_manifests: ["tests/AndroidManifest.xml"], - resource_dirs: [], - srcs: [ - // Kotlin likes all files in the same module for internal - "src/**/*.kt", - "src/**/*.java", - "src/**/I*.aidl", - ":ReleaseJavaFiles", - "tests/src/**/*.kt", - "tests/src/**/*.java", - ":SystemUI-tests-utils", - ], - dont_merge_manifests: true, - static_libs: [ - "SystemUI-tests-base", - "androidx.test.uiautomator_uiautomator", - "mockito-target-extended-minus-junit4", - "androidx.test.ext.junit", - ], - libs: [ - "android.test.runner", - "android.test.base", - "android.test.mock", - ], kotlincflags: ["-Xjvm-default=enable"], aaptflags: [ "--extra-packages", @@ -270,58 +253,6 @@ android_library { }, } -android_app { - name: "SystemUIRobo-stub", - defaults: [ - "platform_app_defaults", - "SystemUI_app_defaults", - ], - srcs: [ - "src/**/*.kt", - "src/**/*.java", - "src/**/I*.aidl", - ":ReleaseJavaFiles", - ], - manifest: "tests/AndroidManifest-base.xml", - static_libs: [ - "SystemUI-tests-base", - ], - aaptflags: [ - "--extra-packages", - "com.android.systemui", - ], - dont_merge_manifests: true, - platform_apis: true, - system_ext_specific: true, - certificate: "platform", - privileged: true, - resource_dirs: [], - - kotlincflags: ["-Xjvm-default=enable"], - dxflags: ["--multi-dex"], - required: [ - "privapp_whitelist_com.android.systemui", - ], - plugins: ["dagger2-compiler"], -} - -android_robolectric_test { - name: "SystemUiRoboTests", - srcs: [ - "tests/robolectric/src/**/*.kt", - "tests/robolectric/src/**/*.java", - ], - libs: [ - "android.test.runner", - "android.test.base", - "android.test.mock", - "truth-prebuilt", - ], - kotlincflags: ["-Xjvm-default=enable"], - instrumentation_for: "SystemUIRobo-stub", - java_resource_dirs: ["tests/robolectric/config"], -} - // Opt-out config for optimizing the SystemUI target using R8. // Disabled via `export SYSTEMUI_OPTIMIZE_JAVA=false`, or explicitly in Make via // `SYSTEMUI_OPTIMIZE_JAVA := false`. diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 11237dca7804..7db68b085090 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -126,6 +126,9 @@ <uses-permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES" /> <uses-permission android:name="android.permission.INPUT_CONSUMER" /> + <!-- DeviceStateManager --> + <uses-permission android:name="android.permission.CONTROL_DEVICE_STATE" /> + <!-- DreamManager --> <uses-permission android:name="android.permission.READ_DREAM_STATE" /> <uses-permission android:name="android.permission.WRITE_DREAM_STATE" /> diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp index f7bcf1faf33a..5df79e1bee94 100644 --- a/packages/SystemUI/animation/Android.bp +++ b/packages/SystemUI/animation/Android.bp @@ -36,8 +36,29 @@ android_library { static_libs: [ "PluginCoreLib", + "androidx.core_core-animation-nodeps", ], manifest: "AndroidManifest.xml", kotlincflags: ["-Xjvm-default=all"], } + +android_test { + name: "SystemUIAnimationLibTests", + + static_libs: [ + "SystemUIAnimationLib", + "androidx.test.ext.junit", + "androidx.test.rules", + "testables", + ], + libs: [ + "android.test.base", + ], + srcs: [ + "**/*.java", + "**/*.kt", + ], + kotlincflags: ["-Xjvm-default=all"], + test_suites: ["general-tests"], +} diff --git a/packages/SystemUI/animation/TEST_MAPPING b/packages/SystemUI/animation/TEST_MAPPING new file mode 100644 index 000000000000..3dc8510bbf24 --- /dev/null +++ b/packages/SystemUI/animation/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "SystemUIAnimationLibTests" + } + ] +} diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/Interpolators.java b/packages/SystemUI/animation/src/com/android/systemui/animation/Interpolators.java index 80634832acd9..9dbb9205b90e 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/Interpolators.java +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/Interpolators.java @@ -27,7 +27,10 @@ import android.view.animation.LinearInterpolator; import android.view.animation.PathInterpolator; /** - * Utility class to receive interpolators from + * Utility class to receive interpolators from. + * + * Make sure that changes made to this class are also reflected in {@link InterpolatorsAndroidX}. + * Please consider using the androidx dependencies featuring better testability altogether. */ public class Interpolators { diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/InterpolatorsAndroidX.java b/packages/SystemUI/animation/src/com/android/systemui/animation/InterpolatorsAndroidX.java new file mode 100644 index 000000000000..8da87feb1fee --- /dev/null +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/InterpolatorsAndroidX.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.animation; + +import android.graphics.Path; +import android.util.MathUtils; + +import androidx.core.animation.AccelerateDecelerateInterpolator; +import androidx.core.animation.AccelerateInterpolator; +import androidx.core.animation.BounceInterpolator; +import androidx.core.animation.DecelerateInterpolator; +import androidx.core.animation.Interpolator; +import androidx.core.animation.LinearInterpolator; +import androidx.core.animation.PathInterpolator; + +/** + * Utility class to receive interpolators from. (androidx compatible version) + * + * This is the androidx compatible version of {@link Interpolators}. Make sure that changes made to + * this class are also reflected in {@link Interpolators}. + * + * Using the androidx versions of {@link androidx.core.animation.ValueAnimator} or + * {@link androidx.core.animation.ObjectAnimator} improves animation testability. This file provides + * the androidx compatible versions of the interpolators defined in {@link Interpolators}. + * AnimatorTestRule can be used in Tests to manipulate the animation under test (e.g. artificially + * advancing the time). + */ +public class InterpolatorsAndroidX { + + /* + * ============================================================================================ + * Emphasized interpolators. + * ============================================================================================ + */ + + /** + * The default emphasized interpolator. Used for hero / emphasized movement of content. + */ + public static final Interpolator EMPHASIZED = createEmphasizedInterpolator(); + + /** + * The accelerated emphasized interpolator. Used for hero / emphasized movement of content that + * is disappearing e.g. when moving off screen. + */ + public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator( + 0.3f, 0f, 0.8f, 0.15f); + + /** + * The decelerating emphasized interpolator. Used for hero / emphasized movement of content that + * is appearing e.g. when coming from off screen + */ + public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator( + 0.05f, 0.7f, 0.1f, 1f); + + + /* + * ============================================================================================ + * Standard interpolators. + * ============================================================================================ + */ + + /** + * The standard interpolator that should be used on every normal animation + */ + public static final Interpolator STANDARD = new PathInterpolator( + 0.2f, 0f, 0f, 1f); + + /** + * The standard accelerating interpolator that should be used on every regular movement of + * content that is disappearing e.g. when moving off screen. + */ + public static final Interpolator STANDARD_ACCELERATE = new PathInterpolator( + 0.3f, 0f, 1f, 1f); + + /** + * The standard decelerating interpolator that should be used on every regular movement of + * content that is appearing e.g. when coming from off screen. + */ + public static final Interpolator STANDARD_DECELERATE = new PathInterpolator( + 0f, 0f, 0f, 1f); + + /* + * ============================================================================================ + * Legacy + * ============================================================================================ + */ + + /** + * The default legacy interpolator as defined in Material 1. Also known as FAST_OUT_SLOW_IN. + */ + public static final Interpolator LEGACY = new PathInterpolator(0.4f, 0f, 0.2f, 1f); + + /** + * The default legacy accelerating interpolator as defined in Material 1. + * Also known as FAST_OUT_LINEAR_IN. + */ + public static final Interpolator LEGACY_ACCELERATE = new PathInterpolator(0.4f, 0f, 1f, 1f); + + /** + * The default legacy decelerating interpolator as defined in Material 1. + * Also known as LINEAR_OUT_SLOW_IN. + */ + public static final Interpolator LEGACY_DECELERATE = new PathInterpolator(0f, 0f, 0.2f, 1f); + + /** + * Linear interpolator. Often used if the interpolator is for different properties who need + * different interpolations. + */ + public static final Interpolator LINEAR = new LinearInterpolator(); + + /* + * ============================================================================================ + * Custom interpolators + * ============================================================================================ + */ + + public static final Interpolator FAST_OUT_SLOW_IN = LEGACY; + public static final Interpolator FAST_OUT_LINEAR_IN = LEGACY_ACCELERATE; + public static final Interpolator LINEAR_OUT_SLOW_IN = LEGACY_DECELERATE; + + /** + * Like {@link #FAST_OUT_SLOW_IN}, but used in case the animation is played in reverse (i.e. t + * goes from 1 to 0 instead of 0 to 1). + */ + public static final Interpolator FAST_OUT_SLOW_IN_REVERSE = + new PathInterpolator(0.8f, 0f, 0.6f, 1f); + public static final Interpolator SLOW_OUT_LINEAR_IN = new PathInterpolator(0.8f, 0f, 1f, 1f); + public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); + public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f); + public static final Interpolator ACCELERATE = new AccelerateInterpolator(); + public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator(); + public static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f); + public static final Interpolator CUSTOM_40_40 = new PathInterpolator(0.4f, 0f, 0.6f, 1f); + public static final Interpolator ICON_OVERSHOT = new PathInterpolator(0.4f, 0f, 0.2f, 1.4f); + public static final Interpolator ICON_OVERSHOT_LESS = new PathInterpolator(0.4f, 0f, 0.2f, + 1.1f); + public static final Interpolator PANEL_CLOSE_ACCELERATED = new PathInterpolator(0.3f, 0, 0.5f, + 1); + public static final Interpolator BOUNCE = new BounceInterpolator(); + /** + * For state transitions on the control panel that lives in GlobalActions. + */ + public static final Interpolator CONTROL_STATE = new PathInterpolator(0.4f, 0f, 0.2f, + 1.0f); + + /** + * Interpolator to be used when animating a move based on a click. Pair with enough duration. + */ + public static final Interpolator TOUCH_RESPONSE = + new PathInterpolator(0.3f, 0f, 0.1f, 1f); + + /** + * Like {@link #TOUCH_RESPONSE}, but used in case the animation is played in reverse (i.e. t + * goes from 1 to 0 instead of 0 to 1). + */ + public static final Interpolator TOUCH_RESPONSE_REVERSE = + new PathInterpolator(0.9f, 0f, 0.7f, 1f); + + /* + * ============================================================================================ + * Functions / Utilities + * ============================================================================================ + */ + + /** + * Calculate the amount of overshoot using an exponential falloff function with desired + * properties, where the overshoot smoothly transitions at the 1.0f boundary into the + * overshoot, retaining its acceleration. + * + * @param progress a progress value going from 0 to 1 + * @param overshootAmount the amount > 0 of overshoot desired. A value of 0.1 means the max + * value of the overall progress will be at 1.1. + * @param overshootStart the point in (0,1] where the result should reach 1 + * @return the interpolated overshoot + */ + public static float getOvershootInterpolation(float progress, float overshootAmount, + float overshootStart) { + if (overshootAmount == 0.0f || overshootStart == 0.0f) { + throw new IllegalArgumentException("Invalid values for overshoot"); + } + float b = MathUtils.log((overshootAmount + 1) / (overshootAmount)) / overshootStart; + return MathUtils.max(0.0f, + (float) (1.0f - Math.exp(-b * progress)) * (overshootAmount + 1.0f)); + } + + /** + * Similar to {@link #getOvershootInterpolation(float, float, float)} but the overshoot + * starts immediately here, instead of first having a section of non-overshooting + * + * @param progress a progress value going from 0 to 1 + */ + public static float getOvershootInterpolation(float progress) { + return MathUtils.max(0.0f, (float) (1.0f - Math.exp(-4 * progress))); + } + + // Create the default emphasized interpolator + private static PathInterpolator createEmphasizedInterpolator() { + Path path = new Path(); + // Doing the same as fast_out_extra_slow_in + path.moveTo(0f, 0f); + path.cubicTo(0.05f, 0f, 0.133333f, 0.06f, 0.166666f, 0.4f); + path.cubicTo(0.208333f, 0.82f, 0.25f, 1f, 1f, 1f); + return new PathInterpolator(path); + } +} diff --git a/packages/SystemUI/animation/tests/com/android/systemui/animation/InterpolatorsAndroidXTest.kt b/packages/SystemUI/animation/tests/com/android/systemui/animation/InterpolatorsAndroidXTest.kt new file mode 100644 index 000000000000..389eed015820 --- /dev/null +++ b/packages/SystemUI/animation/tests/com/android/systemui/animation/InterpolatorsAndroidXTest.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.animation + +import androidx.test.filters.SmallTest +import java.lang.reflect.Modifier +import junit.framework.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@SmallTest +@RunWith(JUnit4::class) +class InterpolatorsAndroidXTest { + + @Test + fun testInterpolatorsAndInterpolatorsAndroidXPublicMethodsAreEqual() { + assertEquals( + Interpolators::class.java.getPublicMethods(), + InterpolatorsAndroidX::class.java.getPublicMethods() + ) + } + + @Test + fun testInterpolatorsAndInterpolatorsAndroidXPublicFieldsAreEqual() { + assertEquals( + Interpolators::class.java.getPublicFields(), + InterpolatorsAndroidX::class.java.getPublicFields() + ) + } + + private fun <T> Class<T>.getPublicMethods() = + declaredMethods + .filter { Modifier.isPublic(it.modifiers) } + .map { it.toString().replace(name, "") } + .toSet() + + private fun <T> Class<T>.getPublicFields() = + fields.filter { Modifier.isPublic(it.modifiers) }.map { it.name }.toSet() +} diff --git a/packages/SystemUI/res-keyguard/drawable/ic_flashlight_off.xml b/packages/SystemUI/res-keyguard/drawable/ic_flashlight_off.xml new file mode 100644 index 000000000000..e850d6823e97 --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable/ic_flashlight_off.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="#1f1f1f" + android:pathData="M8,22V11L6,8V2H18V8L16,11V22ZM12,15.5Q11.375,15.5 10.938,15.062Q10.5,14.625 10.5,14Q10.5,13.375 10.938,12.938Q11.375,12.5 12,12.5Q12.625,12.5 13.062,12.938Q13.5,13.375 13.5,14Q13.5,14.625 13.062,15.062Q12.625,15.5 12,15.5ZM8,5H16V4H8ZM16,7H8V7.4L10,10.4V20H14V10.4L16,7.4ZM12,12Z"/> +</vector> diff --git a/packages/SystemUI/res-keyguard/drawable/ic_flashlight_on.xml b/packages/SystemUI/res-keyguard/drawable/ic_flashlight_on.xml new file mode 100644 index 000000000000..91b9ae56b145 --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable/ic_flashlight_on.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="#1f1f1f" + android:pathData="M6,5V2H18V5ZM12,15.5Q12.625,15.5 13.062,15.062Q13.5,14.625 13.5,14Q13.5,13.375 13.062,12.938Q12.625,12.5 12,12.5Q11.375,12.5 10.938,12.938Q10.5,13.375 10.5,14Q10.5,14.625 10.938,15.062Q11.375,15.5 12,15.5ZM8,22V11L6,8V7H18V8L16,11V22Z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml new file mode 100644 index 000000000000..9a022960d1e3 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml @@ -0,0 +1,21 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <corners android:radius="@dimen/screenrecord_spinner_background_radius"/> + <solid android:color="?androidprv:attr/colorAccentSecondary" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml b/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml new file mode 100644 index 000000000000..34e7d0afcd97 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml @@ -0,0 +1,35 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:paddingMode="stack"> + <item> + <shape android:shape="rectangle"> + <corners android:radius="@dimen/screenrecord_spinner_background_radius" /> + <stroke + android:width="1dp" + android:color="?androidprv:attr/textColorTertiary" /> + <solid android:color="@android:color/transparent"/> + </shape> + </item> + <item + android:drawable="@drawable/ic_ksh_key_down" + android:gravity="end|center_vertical" + android:textColor="?androidprv:attr/textColorPrimary" + android:width="@dimen/screenrecord_spinner_arrow_size" + android:height="@dimen/screenrecord_spinner_arrow_size" + android:end="20dp" /> +</layer-list>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/activity_rear_display_education.xml b/packages/SystemUI/res/layout/activity_rear_display_education.xml new file mode 100644 index 000000000000..73d3f0236fff --- /dev/null +++ b/packages/SystemUI/res/layout/activity_rear_display_education.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center" > + + <androidx.cardview.widget.CardView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:cardElevation="0dp" + app:cardCornerRadius="28dp" + app:cardBackgroundColor="@color/rear_display_overlay_animation_background_color"> + + <com.airbnb.lottie.LottieAnimationView + android:id="@+id/rear_display_folded_animation" + android:layout_width="@dimen/rear_display_animation_width" + android:layout_height="@dimen/rear_display_animation_height" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="fitXY" + app:lottie_rawRes="@raw/rear_display_folded" + app:lottie_autoPlay="true" + app:lottie_repeatMode="reverse"/> + </androidx.cardview.widget.CardView> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/rear_display_fold_bottom_sheet_title" + android:textAppearance="@style/TextAppearance.Dialog.Title" + android:lineSpacingExtra="2sp" + android:paddingTop="@dimen/rear_display_title_top_padding" + android:paddingBottom="@dimen/rear_display_title_bottom_padding" + android:gravity="center_horizontal|center_vertical" + /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/rear_display_bottom_sheet_description" + android:textAppearance="@style/TextAppearance.Dialog.Body" + android:lineSpacingExtra="2sp" + android:translationY="-1.24sp" + android:gravity="center_horizontal|top" + /> +</LinearLayout> diff --git a/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml new file mode 100644 index 000000000000..20b93d9bc40d --- /dev/null +++ b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center" > + + <androidx.cardview.widget.CardView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:cardElevation="0dp" + app:cardCornerRadius="28dp" + app:cardBackgroundColor="@color/rear_display_overlay_animation_background_color"> + + <com.airbnb.lottie.LottieAnimationView + android:id="@+id/rear_display_folded_animation" + android:layout_width="@dimen/rear_display_animation_width" + android:layout_height="@dimen/rear_display_animation_height" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="fitXY" + app:lottie_rawRes="@raw/rear_display_turnaround" + app:lottie_autoPlay="true" + app:lottie_repeatMode="reverse"/> + </androidx.cardview.widget.CardView> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/rear_display_unfold_bottom_sheet_title" + android:textAppearance="@style/TextAppearance.Dialog.Title" + android:lineSpacingExtra="2sp" + android:paddingTop="@dimen/rear_display_title_top_padding" + android:paddingBottom="@dimen/rear_display_title_bottom_padding" + android:gravity="center_horizontal|center_vertical" + /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/rear_display_bottom_sheet_description" + android:textAppearance="@style/TextAppearance.Dialog.Body" + android:lineSpacingExtra="2sp" + android:translationY="-1.24sp" + android:gravity="center_horizontal|top" + /> + + <TextView + android:id="@+id/rear_display_warning_text_view" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/rear_display_bottom_sheet_warning" + android:textAppearance="@style/TextAppearance.Dialog.Body" + android:lineSpacingExtra="2sp" + android:gravity="center_horizontal|top" + /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/screen_record_options.xml b/packages/SystemUI/res/layout/screen_record_options.xml index d6c9e98d8b4d..3f0eea9004a6 100644 --- a/packages/SystemUI/res/layout/screen_record_options.xml +++ b/packages/SystemUI/res/layout/screen_record_options.xml @@ -16,7 +16,8 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical"> + android:orientation="vertical" + android:paddingBottom="@dimen/screenrecord_options_padding_bottom"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" @@ -72,7 +73,7 @@ android:gravity="center_vertical" android:text="@string/screenrecord_taps_label" android:textAppearance="?android:attr/textAppearanceMedium" - android:fontFamily="@*android:string/config_headlineFontFamily" + android:fontFamily="@*android:string/config_bodyFontFamily" android:textColor="?android:attr/textColorPrimary" android:contentDescription="@string/screenrecord_taps_label"/> <Switch diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml index ac46cdb1be24..bd719894e25f 100644 --- a/packages/SystemUI/res/layout/screen_share_dialog.xml +++ b/packages/SystemUI/res/layout/screen_share_dialog.xml @@ -16,7 +16,7 @@ <!-- Scrollview is necessary to fit everything in landscape layout --> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:id="@+id/screen_share_permission_dialog" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -32,10 +32,11 @@ android:gravity="center_horizontal"> <ImageView + android:id="@+id/screen_share_dialog_icon" android:layout_width="@dimen/screenrecord_logo_size" android:layout_height="@dimen/screenrecord_logo_size" - android:src="@drawable/ic_screenrecord" - android:tint="@color/screenrecord_icon_color" + android:src="@drawable/ic_media_projection_permission" + android:tint="?androidprv:attr/colorAccentPrimary" android:importantForAccessibility="no"/> <TextView android:id="@+id/screen_share_dialog_title" @@ -43,34 +44,37 @@ android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:fontFamily="@*android:string/config_headlineFontFamily" - android:layout_marginTop="22dp" - android:layout_marginBottom="15dp"/> + android:layout_marginTop="@dimen/screenrecord_title_margin_top" + android:gravity="center"/> <Spinner android:id="@+id/screen_share_mode_spinner" - android:layout_width="320dp" - android:layout_height="72dp" - android:layout_marginTop="24dp" - android:layout_marginBottom="24dp" /> + android:layout_width="match_parent" + android:layout_height="@dimen/screenrecord_spinner_height" + android:layout_marginTop="@dimen/screenrecord_spinner_margin" + android:layout_marginBottom="@dimen/screenrecord_spinner_margin" + android:gravity="center_vertical" + android:background="@drawable/screenshare_options_spinner_background" + android:popupBackground="@drawable/screenrecord_options_spinner_popup_background"/> <ViewStub android:id="@+id/options_stub" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/text_warning" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/screenrecord_description" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="?android:textColorSecondary" android:gravity="start" - android:layout_marginBottom="20dp"/> + android:lineHeight="@dimen/screenrecord_warning_line_height"/> <!-- Buttons --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:layout_marginTop="36dp"> + android:layout_marginTop="@dimen/screenrecord_buttons_margin_top"> <TextView android:id="@+id/button_cancel" android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml new file mode 100644 index 000000000000..66c215599949 --- /dev/null +++ b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml @@ -0,0 +1,27 @@ +<!-- + Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:id="@android:id/text1" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="?androidprv:attr/textColorOnAccent" + android:singleLine="true" + android:layout_width="match_parent" + android:layout_height="@dimen/screenrecord_spinner_height" + android:gravity="center_vertical" + android:ellipsize="marquee" + android:paddingStart="@dimen/screenrecord_spinner_text_padding_start" + android:paddingEnd="@dimen/screenrecord_spinner_text_padding_end"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/screen_share_dialog_spinner_text.xml b/packages/SystemUI/res/layout/screen_share_dialog_spinner_text.xml new file mode 100644 index 000000000000..4cc4cbae3569 --- /dev/null +++ b/packages/SystemUI/res/layout/screen_share_dialog_spinner_text.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:textAppearance="?android:attr/textAppearanceMedium" + android:fontFamily="@*android:string/config_bodyFontFamily" + android:textColor="?android:textColorPrimary" + android:singleLine="true" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:ellipsize="marquee" + android:paddingStart="@dimen/screenrecord_spinner_text_padding_start" + android:paddingEnd="@dimen/screenrecord_spinner_text_padding_end"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index f7600e606731..64aa629b02f0 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -55,6 +55,7 @@ android:id="@+id/status_bar_start_side_container" android:layout_height="match_parent" android:layout_width="0dp" + android:clipChildren="false" android:layout_weight="1"> <!-- Container that is wrapped around the views on the start half of the status bar. diff --git a/packages/SystemUI/res/raw/rear_display_folded.json b/packages/SystemUI/res/raw/rear_display_folded.json new file mode 100644 index 000000000000..5140f4197ef3 --- /dev/null +++ b/packages/SystemUI/res/raw/rear_display_folded.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":60,"ip":0,"op":181,"w":412,"h":300,"nm":"Close to Open - Generic Version V01","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"SHUTTER_ANIMATION 2","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":270.564,"ix":3},"y":{"a":0,"k":239.916,"ix":4}},"a":{"a":0,"k":[460.228,450.736,0],"ix":1,"l":2},"s":{"a":0,"k":[138.889,138.889,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.528,0],[0,-2.528],[2.528,0],[0,2.528]],"o":[[2.528,0],[0,2.528],[-2.528,0],[0,-2.528]],"v":[[0,-4.5],[4.5,0],[0,4.5],[-4.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 599","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[460.228,450.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[140,140],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"SHUTTER_01","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.337,0],[0,-5.337],[5.337,0],[0,5.337]],"o":[[5.337,0],[0,5.337],[-5.337,0],[0,-5.337]],"v":[[0,-9.5],[9.5,0],[0,9.5],[-9.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 598","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[460.228,450.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"SHUTTER_02","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":196,"st":-90,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"CAMERA_CASING","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.125,149.875,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[20,20,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":77.334,"s":[{"i":[[0.121,-8.986],[-0.129,-6.81],[0,0],[0.079,-13.74],[-0.055,-2.977],[0,0],[-0.084,4.25],[0,5.834],[0,20.89],[-0.063,-6.336]],"o":[[-0.029,2.163],[0.129,6.811],[0,0],[-0.079,13.74],[0.123,6.697],[0,0],[0.045,-2.268],[0,-6.193],[0,-0.486],[0.247,24.895]],"v":[[-248.474,-424.663],[-248.252,-408.338],[-247.986,-395.258],[-248.158,-368.523],[-248.248,-337.322],[-243.792,-329.875],[-243.834,-338.44],[-243.875,-350.098],[-244.25,-495.639],[-248.374,-488.414]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":78,"s":[{"i":[[0.121,-8.986],[-0.035,-6.791],[0,0],[0.257,-54.598],[-0.08,-2.976],[0,0],[-0.084,4.25],[0,5.834],[0,20.89],[0.187,-5.461]],"o":[[-0.029,2.163],[0.035,6.791],[0,0],[-0.257,54.598],[0.121,4.51],[0,0],[0.045,-2.268],[0,-6.193],[0,-0.486],[-0.853,24.882]],"v":[[-246.724,-424.581],[-246.689,-408.295],[-246.611,-395.254],[-247.145,-286.802],[-247.56,-173.885],[-239.293,-170.875],[-239.335,-179.44],[-239.251,-191.098],[-239,-495.889],[-246.437,-493.601]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79,"s":[{"i":[[0.714,-8.993],[0.023,-5.892],[0,0],[0.218,-62.519],[-0.04,-3.021],[0,0],[-2.041,1.97],[0,5.92],[0,21.197],[1.374,-7.356]],"o":[[-0.174,2.184],[-0.023,5.892],[0,0],[-0.218,62.519],[0.061,5.942],[0,0],[0.335,-2.259],[0,-6.284],[0,-0.493],[-3.801,24.629]],"v":[[-249.702,-423.916],[-249.966,-409.403],[-249.968,-398.166],[-250.414,-273.882],[-250.801,-145.067],[-238.043,-139.562],[-231.043,-142.595],[-229.959,-182.924],[-230,-497.57],[-247.031,-494.301]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[1.306,-9],[0.081,-4.992],[0,0],[0.2,-61.534],[0,-3.065],[0,0],[-6.497,19.5],[0,6.005],[0,21.503],[2.562,-9.251]],"o":[[-0.32,2.204],[-0.081,4.992],[0,0],[-0.2,61.535],[0,7.375],[0,0],[0.738,-2.215],[0,-6.375],[0,-0.5],[-6.75,24.375]],"v":[[-252.681,-423.25],[-253.243,-410.511],[-253.325,-401.078],[-253.726,-278.775],[-254.126,-151.875],[-236.876,-143.875],[-224.128,-171.375],[-221.128,-194.75],[-221,-499.25],[-241.375,-496.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81,"s":[{"i":[[0,0],[2.977,-4.617],[0.592,-15.582],[0.085,-28.87],[-7.478,-2.938],[0,0],[-7.716,4.062],[0.774,19.04],[0.351,22.315],[4.742,-7.015]],"o":[[0,0],[-5.02,7.785],[-0.054,1.42],[-0.036,12.426],[7.58,-2.313],[0,0],[6.882,-3.623],[-0.821,-20.201],[-4.272,-4.668],[-5.774,8.542]],"v":[[-281.915,-495.91],[-289.56,-482.16],[-299.005,-452.549],[-298.089,-174.301],[-285.022,-158.312],[-272.428,-163.108],[-254.243,-172.187],[-246.548,-198.415],[-247.911,-507.832],[-271.41,-509.792]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83,"s":[{"i":[[0,0],[5.84,-4.09],[0.943,-15.582],[-0.504,-28.868],[-9.184,-4.813],[0,0],[-12.283,4.062],[0.017,19.08],[0.558,22.315],[10.444,-5.833]],"o":[[0,0],[-9.041,6.332],[-0.086,1.42],[0.293,16.801],[12.066,-2.313],[0,0],[10.956,-3.623],[-0.018,-20.335],[-6.483,-6.543],[-12.057,6.734]],"v":[[-335.521,-505.91],[-351.465,-495.91],[-370.479,-463.799],[-369.043,-170.551],[-352.691,-149.562],[-328.662,-154.983],[-300.058,-162.812],[-286.232,-189.04],[-289.767,-509.707],[-316.694,-517.917]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86,"s":[{"i":[[0,0],[10.236,-2.84],[1.247,-15.582],[0,-28.874],[-6.428,0.187],[0,0],[-16.249,4.062],[0,17.165],[0.739,22.315],[11.672,-3.958]],"o":[[0,0],[-13.709,3.803],[-0.114,1.42],[0,17.426],[15.447,-2.313],[0,0],[14.494,-3.623],[0,-20.252],[-3.545,-8.418],[-17.281,5.861]],"v":[[-411.704,-507.785],[-438.297,-499.035],[-463.451,-466.924],[-464.325,-183.676],[-446.9,-161.437],[-413.235,-166.858],[-377.21,-173.437],[-354.78,-199.04],[-356.455,-507.207],[-381.047,-517.292]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88,"s":[{"i":[[0,0],[11.399,-2.84],[1.389,-15.582],[-0.154,-28.874],[-10.466,-4.813],[0,0],[-18.094,4.062],[0.311,21.54],[0.823,22.315],[12.693,-2.083]],"o":[[0,0],[-15.266,3.803],[-0.127,1.42],[0.136,25.551],[16.344,-2.733],[0,0],[16.14,-3.623],[-0.293,-20.255],[-6.423,-10.918],[-20.046,3.29]],"v":[[-453.081,-516.535],[-484.085,-509.035],[-512.096,-476.924],[-511.208,-201.176],[-491.095,-170.812],[-450.071,-176.858],[-415.594,-182.187],[-391.248,-214.04],[-394.202,-507.207],[-419.568,-523.542]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91,"s":[{"i":[[0,0],[11.98,-2.84],[1.46,-15.582],[-0.514,-28.87],[-22.839,0.574],[0,0],[-19.017,4.062],[-1.512,28.415],[0.865,22.315],[18.516,-1.458]],"o":[[0,0],[-16.044,3.803],[-0.133,1.42],[0.514,28.87],[17.426,-0.438],[0,0],[16.962,-3.623],[1.076,-20.231],[-2.031,-12.793],[-21.281,1.676]],"v":[[-517.52,-526.535],[-550.105,-520.285],[-579.544,-488.174],[-580.475,-228.676],[-552.254,-182.687],[-515.05,-186.858],[-479.472,-193.437],[-453.852,-232.165],[-454.219,-505.957],[-481.641,-531.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96,"s":[{"i":[[0,0],[9.594,-0.965],[1.674,-15.582],[-0.589,-28.87],[-26.176,0.574],[0,0],[-26.125,4.687],[-0.648,20.252],[0.991,22.315],[23.63,-1.458]],"o":[[0,0],[-18.792,1.889],[-0.153,1.42],[0.589,28.87],[19.971,-0.438],[0,0],[19.531,-3.504],[0.648,-20.252],[-5.417,-15.918],[-24.412,1.507]],"v":[[-566.624,-545.91],[-605.219,-542.785],[-638.958,-510.674],[-640.256,-243.676],[-605.048,-197.687],[-564.208,-201.233],[-524.5,-205.937],[-494.422,-252.79],[-495.208,-520.332],[-526.755,-548.542]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101,"s":[{"i":[[0,0],[10.756,0.606],[1.787,-15.582],[-0.629,-28.87],[-29.482,0.187],[0,0],[-26.75,1.562],[-0.693,20.252],[1.058,22.315],[29.006,2.879]],"o":[[0,0],[-20.135,-1.134],[-0.163,1.42],[0.629,28.87],[22.579,-0.143],[0,0],[21.139,-1.234],[0.693,-20.252],[-0.991,-20.899],[-22.881,-2.271]],"v":[[-590.882,-561.535],[-630.768,-559.035],[-666.802,-526.924],[-667.496,-244.926],[-626.768,-198.312],[-587.72,-199.358],[-544.491,-201.562],[-512.976,-245.915],[-513.29,-522.832],[-546.76,-561.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.524,-1.302],[0,0],[-22.316,2.187],[-0.707,20.252],[1.081,22.315],[29.62,2.879]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[23.032,1.051],[0,0],[21.519,-2.108],[0.707,-20.252],[-1.012,-20.899],[-23.365,-2.271]],"v":[[-603.82,-572.785],[-647.049,-572.785],[-683.846,-540.674],[-684.555,-258.676],[-646.156,-212.687],[-598.091,-212.483],[-558.309,-214.687],[-525.505,-260.29],[-527.086,-532.832],[-561.264,-571.667]],"c":true}]},{"t":115,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.524,-1.302],[0,0],[-21.06,0.551],[-0.707,20.252],[1.081,22.315],[29.62,2.879]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[23.032,1.051],[0,0],[21.614,-0.566],[0.707,-20.252],[-1.012,-20.899],[-23.365,-2.271]],"v":[[-605.07,-581.535],[-648.299,-581.535],[-685.096,-549.424],[-685.805,-263.676],[-647.406,-217.687],[-601.841,-216.858],[-560.092,-217.187],[-527.348,-259.04],[-528.336,-541.582],[-562.514,-580.417]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294118524,0.250980407,0.262745112181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":78,"op":241,"st":60,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"FRONT_LENS","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[269.043,44.23,0],"ix":2,"l":2},"a":{"a":0,"k":[387.188,-561.875,0],"ix":1,"l":2},"s":{"a":0,"k":[18.519,18.519,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-10.77,0],[0,-10.77],[10.77,0],[0,10.77]],"o":[[10.77,0],[0,10.77],[-10.77,0],[0,-10.77]],"v":[[1.484,-19.734],[20.984,-0.234],[1.484,19.266],[-18.016,-0.234]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[385.5,-561.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":241,"st":60,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"FRONT_SCREEN 2","parent":5,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[268.577,150.446,0],"ix":2,"l":2},"a":{"a":0,"k":[-2.142,1.067,0],"ix":1,"l":2},"s":{"a":0,"k":[18.894,18.894,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[635,1210],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":50,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.641,0.871],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":241,"st":60,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Figure","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[207.459,144.79,0],"to":[0.312,0,0],"ti":[-1.146,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.334,"s":[209.334,144.79,0],"to":[1.146,0,0],"ti":[-2.125,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.666,"s":[214.334,144.79,0],"to":[2.125,0,0],"ti":[-2.812,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70,"s":[222.084,144.79,0],"to":[2.812,0,0],"ti":[-4.396,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73.334,"s":[231.209,144.79,0],"to":[4.396,0,0],"ti":[-5.104,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[248.459,144.79,0],"to":[5.104,0,0],"ti":[-3.812,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[261.834,144.79,0],"to":[3.812,0,0],"ti":[-2.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[271.334,144.79,0],"to":[2.667,0,0],"ti":[-1.812,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[277.834,144.79,0],"to":[1.812,0,0],"ti":[-1.083,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":106.666,"s":[282.209,144.79,0],"to":[1.083,0,0],"ti":[-0.458,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":113.334,"s":[284.334,144.79,0],"to":[0.458,0,0],"ti":[-0.104,0,0]},{"t":120,"s":[284.959,144.79,0]}],"ix":2,"l":2},"a":{"a":0,"k":[270.209,145.54,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.55,0.55,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.001]},"t":60,"s":[108,108,100]},{"t":120,"s":[106.5,106.5,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.939,-1.387],[6.061,-1.3],[0.907,1.308]],"o":[[1.066,0.711],[2.423,1.734],[-4.85,1.04],[0,0]],"v":[[-0.582,-6.237],[5.035,-2.37],[2.01,5.979],[-6.77,3.354]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.596078455448,0.321568638086,0.239215686917,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.12,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[272.026,152.086],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.926,7.277],[-8.848,0],[-3.783,2.669],[18.309,-0.059],[0.81,-15.17],[-4.916,0]],"o":[[3.926,7.277],[4.982,0],[-0.845,-15.213],[-18.267,0.059],[3.755,2.604],[8.848,0]],"v":[[-0.106,3.616],[20.359,15.839],[33.729,11.589],[-0.12,-15.891],[-33.793,11.7],[-20.571,15.839]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,9.805],[9.805,0],[0,-9.805],[-9.805,0]],"o":[[0,-9.805],[-9.805,0],[0,9.805],[9.805,0]],"v":[[-6.59,-22.526],[-24.345,-40.281],[-42.099,-22.526],[-24.345,-4.772]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337254911661,0.23137255013,0.129411771894,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.47,108.276],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hair","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-7.446,13.962],[0,0],[0,0],[-0.313,2.62],[0.015,4.351],[0,0],[-18.83,0.06],[-0.051,-15.806],[0,0],[-0.49,-2.669],[-1.873,-4.352],[-0.89,-3.988],[0,-4.307],[8.014,-5.508],[12.335,-0.04],[8.035,5.309],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.222,-4.479],[0.309,-2.598],[0,0],[-0.051,-15.806],[18.83,-0.06],[0,0],[0.013,4.276],[0.495,2.702],[3.604,8.387],[0.884,3.962],[0,7.459],[-7.997,5.495],[-12.35,0.04],[-8.04,-5.313],[0,0],[0,-6.072]],"v":[[-36.861,-4.598],[-36.804,-4.703],[-36.772,-4.819],[-34.61,-14.535],[-34.324,-24.06],[-34.324,-24.128],[-0.614,-53.129],[33.278,-24.345],[33.278,-24.252],[33.789,-14.641],[37.134,-4.922],[43.41,12.489],[44.307,23.718],[31.53,43.997],[0.092,53.129],[-31.449,44.589],[-44.307,24.009],[-44.307,23.977]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[4.598,1.656],[-2.64,7.412],[-4.598,-1.656],[2.64,-7.412]],"o":[[-4.6,-1.657],[2.64,-7.412],[4.6,1.657],[-2.64,7.412]],"v":[[30.635,-0.09],[27.088,-16.51],[40.195,-26.931],[43.742,-10.511]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[4.598,-1.656],[2.64,7.412],[-4.598,1.656],[-2.64,-7.412]],"o":[[-4.6,1.657],[-2.64,-7.412],[4.6,-1.657],[2.64,7.412]],"v":[[-32.206,-0.025],[-45.315,-10.446],[-41.768,-26.866],[-28.659,-16.445]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.678431391716,0.403921574354,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.996,145.54],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Head","np":4,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[32.75,0],[5.125,-6.5],[0,0],[0,0],[0.125,7.75]],"o":[[-36.75,0],[-0.25,11],[0,0],[0,0],[-14.25,-12.5]],"v":[[269.5,203.875],[202.375,231.25],[202.125,265.125],[335.375,265.125],[335.375,229.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105865478516,0.450958251953,0.901947021484,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,-5.243]],"o":[[0,0],[0,0],[0,0],[5.243,0],[0,0]],"v":[[335.369,264.28],[202.496,264.441],[202.496,35.601],[325.98,35.551],[335.473,45.044]],"c":true},"ix":2},"nm":"Mask","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.815673828125,0.88232421875,0.980377197266,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Background","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":660,"st":60,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"FOLDABLE_BODY","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.125,149.875,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[20,20,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,-16.75],[0,0],[0.131,-20.875],[0,0],[0,0],[-1.054,43.75],[0,0],[55.442,-0.625],[0,0],[0,0]],"o":[[0,0],[0.07,32.5],[0,0],[0,0],[50.138,1],[0,0],[0.75,-40.75],[0,0],[0,0],[-0.317,13.125]],"v":[[-380.75,-475.25],[-381.945,472.625],[-381.756,573.5],[-381.766,647.625],[278.237,648.25],[356.555,572.75],[356.375,-566.125],[277.933,-644.25],[-380.936,-644.5],[-380.183,-550.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.334,"s":[{"i":[[0,-16.75],[0,0],[0.131,-20.875],[0,0],[0,0],[-1.054,43.75],[0,0],[55.442,-0.625],[0,0],[0,0]],"o":[[0,0],[0.07,32.5],[0,0],[0,0],[50.138,1],[0,0],[0.75,-40.75],[0,0],[0,0],[-0.317,13.125]],"v":[[-373.625,-475],[-373.633,472.562],[-373.444,573.438],[-373.454,647.562],[287.112,648.375],[364.93,573.625],[364.75,-566.938],[285.995,-645],[-373.811,-644.25],[-373.058,-550.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.666,"s":[{"i":[[0,-16.75],[0,0],[0.131,-20.875],[0,0],[0,0],[-1.054,43.75],[0,0],[55.442,-0.625],[0,0],[0,0]],"o":[[0,0],[0.07,32.5],[0,0],[0,0],[50.138,1],[0,0],[0.75,-40.75],[0,0],[0,0],[-0.317,13.125]],"v":[[-350,-475.25],[-349.82,472.5],[-349.631,573.375],[-349.641,647.5],[311.487,647],[388.805,573],[389.125,-566.75],[310.058,-644.75],[-350.186,-644.5],[-349.433,-550.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70,"s":[{"i":[[0,-16.75],[0,0],[0.131,-20.875],[0,0],[0,0],[-1.054,43.75],[0,0],[54.942,-0.625],[0,0],[0,0]],"o":[[0,0],[0.07,32.5],[0,0],[0,0],[50.138,1],[0,0],[0.187,-41.375],[0,0],[0,0],[-0.317,13.125]],"v":[[-315.875,-476.875],[-315.445,471],[-315.256,571.875],[-315.266,646],[348.612,647.562],[427.555,572.75],[427.438,-565.75],[349.058,-643.688],[-316.077,-643.625],[-315.308,-552.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73.334,"s":[{"i":[[0,-16.75],[0,0],[0.131,-20.875],[0,0],[0,0],[-1.054,43.75],[0,0],[54.442,-0.625],[0,0],[0,0]],"o":[[0,0],[0.07,32.5],[0,0],[0,0],[50.138,1],[0,0],[0.75,-40.75],[0,0],[0,0],[-0.317,13.125]],"v":[[-278.75,-478],[-278.57,469.75],[-278.381,570.625],[-278.391,644.75],[395.237,645.125],[471.554,571],[471.25,-564],[393.808,-642.125],[-278.968,-642.25],[-278.183,-553.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,-16.75],[0,0],[-0.119,-21.25],[0,0],[0,0],[-1.054,42.938],[0,0],[54.442,-0.625],[0,0],[0,0]],"o":[[0,0],[0.32,32.625],[0,0],[0,0],[50.075,0.562],[0,0],[0.75,-40.75],[0,0],[0,0],[0.183,12.75]],"v":[[-248.25,-479],[-248.82,468.5],[-248.381,550.25],[-248.516,643.75],[440.3,644.25],[515.804,570.375],[516,-564.375],[438.058,-641],[-248.468,-640.125],[-248.308,-541.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79.334,"s":[{"i":[[0,-16.75],[0,0],[0.081,-18.8],[0,0],[0,0],[-1.054,42.287],[0,0],[54.442,-0.625],[0,0],[0,0]],"o":[[0,0],[0.52,32.725],[0,0],[0,0],[50.025,0.212],[0,0],[0.75,-40.75],[0,0],[0,0],[-1.317,12.05]],"v":[[-223.65,-479.7],[-224.12,467.9],[-224.081,534.35],[-224.116,642.5],[471.15,643.15],[548.004,570.275],[548.2,-564.675],[468.658,-640.1],[-224.668,-638.65],[-224.208,-523.1]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[0,-16.75],[0,0],[-2.744,-18],[0,0],[0,0],[-1.054,42.125],[0,0],[54.442,-0.625],[0,0],[0,0]],"o":[[0,0],[0.57,32.75],[0,0],[0,0],[50.013,0.125],[0,0],[0.75,-40.75],[0,0],[0,0],[-1.692,11.875]],"v":[[-233.75,-479.75],[-233.57,467.5],[-229.881,530.125],[-213.641,642.5],[478.862,642.875],[556.054,570.25],[556.25,-564.75],[476.308,-639.875],[-212.468,-638.5],[-230.683,-518.375]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80.666,"s":[{"i":[[0.133,-15.433],[0,0],[-4.881,-15.762],[0,0],[0,0],[-1.067,41.975],[0,0],[54.08,-0.675],[0,0],[0,0]],"o":[[0,0],[0.458,32.95],[0,0],[0,0],[49.838,0.162],[0,0],[0.75,-40.625],[0,0],[0,0],[-6.455,9.608]],"v":[[-267.883,-471.067],[-267.329,462.242],[-262.735,514.346],[-201.341,642],[486.187,642.638],[563.142,570.212],[563.35,-564.412],[483.87,-639.625],[-201.81,-638.275],[-260.045,-517.358]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82,"s":[{"i":[[0.4,-12.8],[0,0],[-9.156,-11.287],[0,0],[0,0],[-1.092,41.675],[0,0],[53.355,-0.775],[0,0],[0,0]],"o":[[0,0],[0.233,33.35],[0,0],[0,0],[49.488,0.238],[0,0],[0.75,-40.375],[0,0],[0,0],[-10.48,6.825]],"v":[[-331.65,-460.45],[-331.47,451.725],[-319.444,518.037],[-181.241,641.75],[500.837,642.162],[577.317,570.138],[577.55,-563.737],[498.995,-639.125],[-180.493,-637.825],[-318.77,-515.325]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[0,-16.75],[0,0],[-13.431,-6.812],[0,0],[0,0],[-1.117,41.375],[0,0],[52.63,-0.875],[0,0],[0,0]],"o":[[0,0],[0.008,33.75],[0,0],[0,0],[49.138,0.312],[0,0],[0.75,-40.125],[0,0],[0,0],[-18.005,8.375]],"v":[[-387.75,-461.75],[-388.82,454.125],[-369.569,523.312],[-159.641,641.25],[515.487,641.688],[591.492,570.062],[591.75,-563.062],[514.12,-638.625],[-160.843,-637.375],[-367.495,-521.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.666,"s":[{"i":[[0,-16.75],[0,0],[-20.006,-7.188],[0,0],[0,0],[-1.142,41.075],[0,0],[49.955,-0.925],[0,0],[0,0]],"o":[[0,0],[-0.217,34.15],[0,0],[0,0],[48.788,0.387],[0,0],[0.75,-39.875],[0,0],[0,0],[-24.98,7.975]],"v":[[-439.2,-468.15],[-438.72,458.425],[-413.244,530.237],[-141.041,640.35],[527.537,641.212],[603.067,569.987],[603.15,-564.787],[526.445,-638.125],[-143.993,-637.125],[-411.07,-528.125]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0,-16.75],[0,0],[-29.869,-7.75],[0,0],[0,0],[-1.179,40.625],[0,0],[45.942,-1],[0,0],[0,0]],"o":[[0,0],[-0.555,34.75],[0,0],[0,0],[48.263,0.5],[0,0],[0.75,-39.5],[0,0],[0,0],[-35.442,7.375]],"v":[[-503.25,-477.75],[-503.57,464.25],[-468.756,540],[-113.141,639],[545.612,640.5],[620.429,569.875],[620.25,-567.375],[544.933,-637.375],[-118.718,-636.75],[-463.308,-537.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0.062,-18.625],[0,0],[-31.869,-6.438],[0,0],[0,0],[-1.179,40.438],[0,0],[44.63,-1],[0,0],[0,0]],"o":[[0,0],[-0.43,34.75],[0,0],[0,0],[47.638,0.625],[0,0],[0.5,-39.062],[0,0],[0,0],[-38.817,5.938]],"v":[[-584.938,-494.688],[-585.445,486.188],[-542.506,557.375],[-88.141,639],[570.612,639.75],[646.054,568.625],[646.188,-566.875],[570.495,-636.625],[-92.093,-636],[-537.183,-555.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0.125,-20.5],[0,0],[-33.869,-5.125],[0,0],[0,0],[-1.179,40.25],[0,0],[43.317,-1],[0,0],[0,0]],"o":[[0,0],[-0.305,34.75],[0,0],[0,0],[47.013,0.75],[0,0],[0.25,-38.625],[0,0],[0,0],[-42.192,4.5]],"v":[[-640.125,-510.625],[-640.32,507.125],[-589.256,573.75],[-63.141,639],[591.112,639.25],[667.179,567.625],[666.625,-567.5],[593.058,-635.5],[-65.468,-635.25],[-584.558,-571.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96.666,"s":[{"i":[[0.062,-30.685],[0,0],[-36.306,-4.562],[0,0],[0,0],[-0.59,40.56],[0,0],[43.317,-1],[0,0],[0,0]],"o":[[0,0],[-0.43,36.25],[0,0],[0,0],[45.45,0.25],[0,0],[0.25,-38.625],[0,0],[0,0],[-41.442,3.938]],"v":[[-676.125,-519.625],[-676.008,522.062],[-617.819,589.812],[-46.391,638.5],[609.862,638.75],[684.617,567.25],[684.375,-566.125],[610.808,-634.75],[-47.593,-634.5],[-616.558,-587.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[0,-40.869],[0,0],[-38.744,-4],[0,0],[0,0],[0,40.869],[0,0],[43.317,-1],[0,0],[0,0]],"o":[[0,0],[-0.555,37.75],[0,0],[0,0],[43.888,-0.25],[0,0],[0.25,-38.625],[0,0],[0,0],[-40.692,3.375]],"v":[[-697.625,-528.125],[-696.945,535.5],[-634.381,602.875],[-29.641,638],[625.612,638.25],[699.054,566.875],[699.125,-564.75],[625.558,-634],[-29.718,-633.75],[-633.558,-599.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":106.666,"s":[{"i":[[0,-40.869],[0,0],[-42.994,-3.25],[0,0],[0,0],[0,40.869],[0,0],[43.317,-1],[0,0],[0,0]],"o":[[0,0],[-0.93,42.625],[0,0],[0,0],[43.888,-0.25],[0,0],[0.25,-38.625],[0,0],[0,0],[-41.067,2.125]],"v":[[-715.875,-547.625],[-715.945,550.5],[-647.881,622.875],[-8.891,637.25],[646.487,637.75],[719.679,565.375],[718.875,-563.25],[646.183,-633.75],[-9.218,-633.875],[-649.058,-619.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":113.334,"s":[{"i":[[0,-40.869],[0,0],[-44.369,-2],[0,0],[0,0],[0,40.869],[0,0],[43.317,-1],[0,0],[0,0]],"o":[[0,0],[-0.305,42.5],[0,0],[0,0],[43.888,-0.25],[0,0],[0.25,-38.625],[0,0],[0,0],[-40.423,0]],"v":[[-720.125,-562.375],[-720.82,561.25],[-649.131,634],[3.109,637.25],[658.987,636.625],[729.679,566.125],[729.625,-564.75],[657.308,-633.375],[2.907,-633.625],[-649.808,-630.5]],"c":true}]},{"t":120,"s":[{"i":[[0,-40.869],[0,0],[-46.994,-1.25],[0,0],[0,0],[0,40.869],[0,0],[43.317,-1],[0,0],[0,0]],"o":[[0,0],[-0.305,42.5],[0,0],[0,0],[43.888,-0.25],[0,0],[0.75,-40],[0,0],[0,0],[-40.423,0]],"v":[[-721.75,-564.375],[-721.57,561.5],[-649.631,637.75],[-3.641,637.25],[659.862,637],[733.179,565.625],[732.75,-564.875],[659.058,-634.25],[2.032,-633.75],[-648.683,-634.375]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"rd","nm":"Round Corners 1","r":{"a":0,"k":18,"ix":1},"ix":2,"mn":"ADBE Vector Filter - RC","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-3,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":241,"st":60,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"BUTTON","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[71.498,114.825,0],"ix":2,"l":2},"a":{"a":0,"k":[-698.509,46.873,0],"ix":1,"l":2},"s":{"a":0,"k":[40,18,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-0.549,1.538],[0,0]],"o":[[0,0],[-0.554,-3.125],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[27.005,73.269],[26.312,72.137],[26,64.269],[25.741,-76.022],[26.183,-82.526],[27.125,-83.046]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":98,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-0.987,1.288],[0,0]],"o":[[0,0],[-0.741,-2.125],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[10.88,76.769],[7.625,75.627],[6.812,68.26],[6.553,-78.594],[7.808,-85.536],[11.375,-86.11]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-1.424,1.038],[0,0]],"o":[[0,0],[-0.929,-1.125],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-1.995,80.394],[-4.313,79.127],[-5.625,72.26],[-5.884,-81.156],[-3.817,-88.536],[-1.625,-89.046]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-1.581,0.831],[0,0]],"o":[[0,0],[-1.154,-1.025],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-4.92,81.663],[-10.263,80.552],[-11.8,73.81],[-11.934,-81.831],[-9.692,-89.236],[-4.55,-89.626]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":103.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-1.817,0.519],[0,0]],"o":[[0,0],[-1.491,-0.875],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-10.917,83.519],[-16.922,82.69],[-18.797,76.135],[-18.744,-82.844],[-16.239,-90.286],[-10.547,-90.546]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.052,0.208],[0,0]],"o":[[0,0],[-1.829,-0.725],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-16.289,85.394],[-21.456,84.827],[-23.669,78.46],[-23.428,-83.856],[-20.661,-91.336],[-15.919,-91.446]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":106.666,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.054,-0.625],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-20.027,86.635],[-23.438,86.252],[-25.875,80.01],[-25.509,-84.531],[-22.567,-92.036],[-19.656,-92.055]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.069,-0.563],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-20.345,86.897],[-24.538,86.552],[-26.994,80.535],[-26.609,-85.031],[-23.661,-92.186],[-19.969,-92.205]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":109.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.116,-0.375],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-21.718,87.685],[-26.535,87.452],[-29.048,82.11],[-28.605,-86.531],[-25.64,-92.636],[-21.323,-92.655]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.163,-0.188],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-22.982,88.472],[-27.674,88.352],[-30.243,83.685],[-29.742,-88.031],[-26.76,-93.086],[-22.568,-93.105]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":112.666,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.194,-0.063],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-24.293,88.997],[-28.485,88.952],[-31.091,84.735],[-30.553,-89.031],[-27.558,-93.386],[-23.866,-93.405]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":113.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.209,0],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-24.558,89.26],[-28.188,89.252],[-30.812,85.26],[-30.255,-89.531],[-27.255,-93.536],[-24.125,-93.555]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":114.666,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.209,0],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-24.765,89.36],[-28.394,89.352],[-31.219,85.359],[-30.748,-89.532],[-27.548,-93.536],[-24.419,-93.555]],"c":true}]},{"t":120,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.209,0],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-25.373,90.005],[-27.502,89.998],[-31.127,86],[-31.005,-89.291],[-27.005,-93.291],[-25.375,-93.31]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-698.509,46.873],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":96,"op":241,"st":60,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"BUTTON 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[71.498,179.325,0],"ix":2,"l":2},"a":{"a":0,"k":[-698.509,46.873,0],"ix":1,"l":2},"s":{"a":0,"k":[40,25,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-0.549,1.538],[0,0]],"o":[[0,0],[-0.554,-3.125],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[27.005,73.269],[26.312,72.137],[26,64.269],[25.741,-76.022],[26.183,-82.526],[27.125,-83.046]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":98,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-0.987,1.288],[0,0]],"o":[[0,0],[-0.741,-2.125],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[10.88,76.769],[7.625,75.627],[6.812,68.26],[6.553,-78.594],[7.808,-85.536],[11.375,-86.11]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-1.424,1.038],[0,0]],"o":[[0,0],[-0.929,-1.125],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-1.995,80.394],[-4.313,79.127],[-5.625,72.26],[-5.884,-81.156],[-3.817,-88.536],[-1.625,-89.046]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-1.581,0.831],[0,0]],"o":[[0,0],[-1.154,-1.025],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-4.92,81.663],[-10.263,80.552],[-11.8,73.81],[-11.934,-81.831],[-9.692,-89.236],[-4.55,-89.626]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":103.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-1.817,0.519],[0,0]],"o":[[0,0],[-1.491,-0.875],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-10.917,83.519],[-16.922,82.69],[-18.797,76.135],[-18.744,-82.844],[-16.239,-90.286],[-10.547,-90.546]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.052,0.208],[0,0]],"o":[[0,0],[-1.829,-0.725],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-16.289,85.394],[-21.456,84.827],[-23.669,78.46],[-23.428,-83.856],[-20.661,-91.336],[-15.919,-91.446]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":106.666,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.054,-0.625],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-20.027,86.635],[-23.438,86.252],[-25.875,80.01],[-25.509,-84.531],[-22.567,-92.036],[-19.656,-92.055]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.069,-0.563],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-20.345,86.897],[-24.538,86.552],[-26.994,80.535],[-26.609,-85.031],[-23.661,-92.186],[-19.969,-92.205]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":109.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.116,-0.375],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-21.718,87.685],[-26.535,87.452],[-29.048,82.11],[-28.605,-86.531],[-25.64,-92.636],[-21.323,-92.655]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.163,-0.188],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-22.982,88.472],[-27.674,88.352],[-30.243,83.685],[-29.742,-88.031],[-26.76,-93.086],[-22.568,-93.105]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":112.666,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.194,-0.063],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-24.293,88.997],[-28.485,88.952],[-31.091,84.735],[-30.553,-89.031],[-27.558,-93.386],[-23.866,-93.405]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":113.334,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.209,0],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-24.558,89.26],[-28.188,89.252],[-30.812,85.26],[-30.255,-89.531],[-27.255,-93.536],[-24.125,-93.555]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":114.666,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.209,0],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-24.765,89.36],[-28.394,89.352],[-31.219,85.359],[-30.748,-89.532],[-27.548,-93.536],[-24.419,-93.555]],"c":true}]},{"t":120,"s":[{"i":[[0,0],[0,0],[0,2.209],[0,0],[-2.209,0],[0,0]],"o":[[0,0],[-2.209,0],[0,0],[0,-2.209],[0,0],[0,0]],"v":[[-25.373,89.63],[-27.502,89.623],[-31.127,85.625],[-31.005,-89.666],[-27.005,-93.666],[-25.375,-93.685]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-698.509,46.873],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":96,"op":241,"st":60,"bm":0}],"markers":[]}
\ No newline at end of file diff --git a/packages/SystemUI/res/raw/rear_display_turnaround.json b/packages/SystemUI/res/raw/rear_display_turnaround.json new file mode 100644 index 000000000000..82204c726e8d --- /dev/null +++ b/packages/SystemUI/res/raw/rear_display_turnaround.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":60,"ip":0,"op":181,"w":412,"h":300,"nm":"Turnaround - Generic Version V01","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"SHUTTER_ANIMATION 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":55,"s":[100]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":320.842,"ix":3},"y":{"a":0,"k":149.716,"ix":4}},"a":{"a":0,"k":[460.228,450.736,0],"ix":1,"l":2},"s":{"a":0,"k":[150,150,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.528,0],[0,-2.528],[2.528,0],[0,2.528]],"o":[[2.528,0],[0,2.528],[-2.528,0],[0,-2.528]],"v":[[0,-4.5],[4.5,0],[0,4.5],[-4.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 599","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[460.228,450.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[140,140],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"SHUTTER_01","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.337,0],[0,-5.337],[5.337,0],[0,5.337]],"o":[[5.337,0],[0,5.337],[-5.337,0],[0,-5.337]],"v":[[0,-9.5],[9.5,0],[0,9.5],[-9.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 598","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[460.228,450.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"SHUTTER_02","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":-90,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"SHUTTER_ANIMATION","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":51,"s":[0]},{"t":56,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":286.342,"ix":3},"y":{"a":0,"k":245.716,"ix":4}},"a":{"a":0,"k":[460.228,450.736,0],"ix":1,"l":2},"s":{"a":0,"k":[150,150,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.528,0],[0,-2.528],[2.528,0],[0,2.528]],"o":[[2.528,0],[0,2.528],[-2.528,0],[0,-2.528]],"v":[[0,-4.5],[4.5,0],[0,4.5],[-4.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 599","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[460.228,450.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[140,140],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":129,"s":[0]},{"t":139,"s":[100]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"SHUTTER_01","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.337,0],[0,-5.337],[5.337,0],[0,5.337]],"o":[[5.337,0],[0,5.337],[-5.337,0],[0,-5.337]],"v":[[0,-9.5],[9.5,0],[0,9.5],[-9.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 598","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[460.228,450.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":129,"s":[0]},{"t":139,"s":[100]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"SHUTTER_02","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":129,"op":279,"st":39,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"PATCH 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[207.062,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":99.166,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[54.347,-125.337],[54.347,125.337],[-15.847,125.337],[-15.847,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[34.347,-125.337],[34.347,125.337],[-35.847,125.337],[-35.847,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":109.166,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.683,-125.337],[-3.683,125.337],[-73.877,125.337],[-73.877,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":110,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.867,-125.337],[-3.867,125.337],[-74.061,125.337],[-74.061,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":113.334,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.606,-125.337],[-1.606,125.337],[-71.799,125.337],[-71.799,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":115,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.775,-125.337],[0.775,125.337],[-69.418,125.337],[-69.418,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":117.5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.347,-125.337],[4.347,125.337],[-65.847,125.337],[-65.847,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":121.666,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[9.686,-125.337],[9.686,125.337],[-60.508,125.337],[-60.508,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":122.5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.954,-125.337],[11.954,125.337],[-58.24,125.337],[-58.24,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":125.834,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[14.759,-125.337],[14.759,125.337],[-55.435,125.337],[-55.435,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126.666,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.668,-125.337],[15.668,125.337],[-54.525,125.337],[-54.525,-125.337]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":128.334,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.987,-125.337],[15.987,125.337],[-54.206,125.337],[-54.206,-125.337]],"c":true}]},{"t":135,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.847,-125.337],[16.847,125.337],[-53.347,125.337],[-53.347,-125.337]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-674.097,51.337],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":99,"op":300,"st":60,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"PATCH","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[207.908,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[722.046,-80],[722.046,165.813],[708.25,165.813],[708.25,-80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[736.168,-80],[736.168,165.813],[722.372,165.813],[722.372,-80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.834,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[737.98,-80],[737.98,165.813],[724.184,165.813],[724.184,-80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.666,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[739.435,-80],[739.435,165.813],[725.639,165.813],[725.639,-80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":67.5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[740.796,-80],[740.796,165.813],[727,165.813],[727,-80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":69.166,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[743.651,-79.231],[743.651,166.583],[729.855,166.583],[729.855,-79.231]],"c":true}]},{"t":72.5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[738.112,-77.692],[738.112,168.121],[724.316,168.121],[724.316,-77.692]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":74,"st":60,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"BUTTON_OUT_BOTTOM 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":60,"s":[206.312,95.219,0],"to":[0,-2.417,0],"ti":[0,0,0]},{"i":{"x":0.333,"y":1},"o":{"x":0.167,"y":0.167},"t":88,"s":[206.312,80.719,0],"to":[0,0,0],"ti":[0,-2.417,0]},{"t":128,"s":[206.312,95.219,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,18,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,-9.113],[0,0],[3.544,-0.062],[0,9.113],[0,0],[-1.905,0.228]],"o":[[0,0],[0,9.113],[-1.908,0.034],[0,0],[0,-9.113],[4.17,-0.5]],"v":[[687.673,-97.826],[687.673,65.299],[679.205,76.875],[675.75,65.375],[675.75,-97.75],[679.205,-108.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65,"s":[{"i":[[0,-9.113],[0,0],[4.532,-0.062],[0,9.113],[0,0],[-2.436,0.228]],"o":[[0,0],[0,9.113],[-2.44,0.034],[0,0],[0,-9.113],[5.332,-0.5]],"v":[[699.977,-97.944],[699.977,68.306],[689.293,80],[684.875,68.5],[684.875,-97.75],[689.293,-108.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70,"s":[{"i":[[0,-9.113],[0,0],[4.532,-0.062],[0,9.113],[0,0],[-2.436,0.228]],"o":[[0,0],[0,9.113],[-2.44,0.034],[0,0],[0,-9.113],[5.332,-0.5]],"v":[[711.227,-100.491],[711.227,76.697],[700.543,87.875],[696.125,76.375],[696.125,-100.812],[700.543,-111.688]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73,"s":[{"i":[[0,-9.113],[0,0],[5.113,-0.062],[0,9.113],[0,0],[-2.748,0.228]],"o":[[0,0],[0,9.113],[-2.753,0.034],[0,0],[0,-9.113],[6.016,-0.5]],"v":[[700.685,-102.905],[700.685,81.345],[692.568,93.125],[687.583,81.625],[687.583,-102.625],[692.568,-113.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":74.166,"s":[{"i":[[0,-9.113],[0,0],[5.694,-0.062],[0,9.113],[0,0],[-3.061,0.228]],"o":[[0,0],[0,9.113],[-3.065,0.034],[0,0],[0,-9.113],[6.699,-0.5]],"v":[[691.581,-103.125],[691.581,83.5],[686.03,95],[680.479,83.5],[680.479,-103.125],[686.03,-114]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,-9.113],[0,0],[6.275,-0.062],[0,9.113],[0,0],[-3.373,0.228]],"o":[[0,0],[0,9.113],[-3.378,0.034],[0,0],[0,-9.113],[7.383,-0.5]],"v":[[683.359,-103.625],[683.359,85.375],[677.242,96.875],[671.125,85.375],[671.125,-103.625],[677.242,-114.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75.834,"s":[{"i":[[0,-9.113],[0,0],[6.856,-0.062],[0,9.113],[0,0],[-3.685,0.228]],"o":[[0,0],[0,9.113],[-3.691,0.034],[0,0],[0,-9.113],[8.066,-0.5]],"v":[[672.305,-104.125],[672.305,87.25],[665.621,98.75],[658.938,87.25],[658.938,-104.125],[665.621,-115]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,-9.113],[0,0],[7.438,-0.062],[0,9.113],[0,0],[-3.997,0.228]],"o":[[0,0],[0,9.113],[-4.004,0.034],[0,0],[0,-9.113],[8.75,-0.5]],"v":[[657.5,-104.625],[657.5,89.125],[650.25,100.625],[643,89.125],[643,-104.625],[650.25,-115.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":77.5,"s":[{"i":[[0,-9.113],[0,0],[7.149,-0.047],[0,9.113],[0,0],[-4.569,0.171]],"o":[[0,0],[0,9.113],[-4.573,0.025],[0,0],[0,-9.113],[8.133,-0.375]],"v":[[637.562,-104.531],[637.562,90.531],[629.281,103.281],[621,90.531],[621,-104.531],[629.281,-116.812]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":78.334,"s":[{"i":[[0,-9.113],[0,0],[6.86,-0.031],[0,9.113],[0,0],[-5.14,0.114]],"o":[[0,0],[0,9.113],[-5.143,0.017],[0,0],[0,-9.113],[7.516,-0.25]],"v":[[612.625,-104.438],[612.625,91.938],[603.312,105.938],[594,91.938],[594,-104.438],[603.312,-118.125]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79.166,"s":[{"i":[[0,-9.113],[0,0],[6.571,-0.016],[0,9.113],[0,0],[-5.711,0.057]],"o":[[0,0],[0,9.113],[-5.713,0.008],[0,0],[0,-9.113],[6.899,-0.125]],"v":[[580.188,-104.094],[580.188,93.594],[569.844,108.844],[559.5,93.594],[559.5,-104.094],[569.844,-119.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[0,-9.113],[0,0],[6.282,0],[0,9.113],[0,0],[-6.282,0]],"o":[[0,0],[0,9.113],[-6.282,0],[0,0],[0,-9.113],[6.282,0]],"v":[[540.25,-103.75],[540.25,95.25],[528.875,111.75],[517.5,95.25],[517.5,-103.75],[528.875,-120.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80.834,"s":[{"i":[[0,-9.113],[0,0],[6.731,0],[0,9.113],[0,0],[-6.731,0]],"o":[[0,0],[0,9.113],[-6.731,0],[0,0],[0,-9.113],[6.731,0]],"v":[[491.25,-104.562],[491.25,97.688],[479.062,114.188],[466.875,97.688],[466.875,-104.562],[479.062,-121.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0,-9.113],[0,0],[7.18,0],[0,9.113],[0,0],[-7.18,0]],"o":[[0,0],[0,9.113],[-7.18,0],[0,0],[0,-9.113],[7.18,0]],"v":[[432.958,-105.375],[432.958,100.125],[419.958,116.625],[406.958,100.125],[406.958,-105.375],[419.958,-121.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.5,"s":[{"i":[[0,-9.113],[0,0],[7.628,0],[0,9.113],[0,0],[-7.628,0]],"o":[[0,0],[0,9.113],[-7.628,0],[0,0],[0,-9.113],[7.628,0]],"v":[[364.854,-106.188],[364.854,102.562],[351.042,119.062],[337.229,102.562],[337.229,-106.188],[351.042,-122.688]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[0,-9.113],[0,0],[8.077,0],[0,9.113],[0,0],[-8.077,0]],"o":[[0,0],[0,9.113],[-8.077,0],[0,0],[0,-9.113],[8.077,0]],"v":[[286.75,-107],[286.75,105],[272.125,121.5],[257.5,105],[257.5,-107],[272.125,-123.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[0,-9.113],[0,0],[8.33,0],[0,9.113],[0,0],[-8.33,0]],"o":[[0,0],[0,9.113],[-8.33,0],[0,0],[0,-9.113],[8.33,0]],"v":[[201.667,-107.5],[201.667,106.167],[186.583,122.667],[171.5,106.167],[171.5,-107.5],[186.583,-124]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85,"s":[{"i":[[0,-9.113],[0,0],[8.583,0],[0,9.113],[0,0],[-8.583,0]],"o":[[0,0],[0,9.113],[-8.583,0],[0,0],[0,-9.113],[8.583,0]],"v":[[110.333,-108],[110.333,107.333],[94.792,123.833],[79.25,107.333],[79.25,-108],[94.792,-124.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85.834,"s":[{"i":[[0,-9.113],[0,0],[8.837,0],[0,9.113],[0,0],[-8.837,0]],"o":[[0,0],[0,9.113],[-8.837,0],[0,0],[0,-9.113],[8.837,0]],"v":[[16.5,-108.5],[16.5,108.5],[0.5,125],[-15.5,108.5],[-15.5,-108.5],[0.5,-125]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0,-9.113],[0,0],[8.698,0],[0,9.113],[0,0],[-8.699,0]],"o":[[0,0],[0,9.113],[-8.699,0],[0,0],[0,-9.113],[8.698,0]],"v":[[-75.766,-108.229],[-75.766,107.667],[-91.516,124.167],[-107.266,107.667],[-107.266,-108.229],[-91.516,-124.729]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0,-9.113],[0,0],[8.56,0],[0,9.113],[0,0],[-8.56,0]],"o":[[0,0],[0,9.113],[-8.56,0],[0,0],[0,-9.113],[8.56,0]],"v":[[-166.781,-107.958],[-166.781,106.833],[-182.281,123.333],[-197.781,106.833],[-197.781,-107.958],[-182.281,-124.458]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88.334,"s":[{"i":[[0,-9.113],[0,0],[8.422,0],[0,9.113],[0,0],[-8.422,0]],"o":[[0,0],[0,9.113],[-8.422,0],[0,0],[0,-9.113],[8.422,0]],"v":[[-252.172,-107.688],[-252.172,106],[-267.422,122.5],[-282.672,106],[-282.672,-107.688],[-267.422,-124.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":89.166,"s":[{"i":[[0,-9.113],[0,0],[8.284,0],[0,9.113],[0,0],[-8.284,0]],"o":[[0,0],[0,9.113],[-8.284,0],[0,0],[0,-9.113],[8.284,0]],"v":[[-330.062,-107.417],[-330.062,105.167],[-345.062,121.667],[-360.062,105.167],[-360.062,-107.417],[-345.062,-123.917]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0,-9.113],[0,0],[8.146,0],[0,9.113],[0,0],[-8.146,0]],"o":[[0,0],[0,9.113],[-8.146,0],[0,0],[0,-9.113],[8.146,0]],"v":[[-400.781,-107.146],[-400.781,103.396],[-415.531,119.896],[-430.281,103.396],[-430.281,-107.146],[-415.531,-123.646]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90.834,"s":[{"i":[[0,-9.113],[0,0],[8.008,0],[0,9.113],[0,0],[-8.008,0]],"o":[[0,0],[0,9.113],[-8.008,0],[0,0],[0,-9.113],[8.008,0]],"v":[[-462.75,-106.875],[-462.75,101.625],[-477.25,118.125],[-491.75,101.625],[-491.75,-106.875],[-477.25,-123.375]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91.666,"s":[{"i":[[0,-9.113],[0,0],[7.525,0],[0,9.113],[0,0],[-7.525,0]],"o":[[0,0],[0,9.113],[-7.525,0],[0,0],[0,-9.113],[7.525,0]],"v":[[-518.308,-106.5],[-518.308,100.125],[-531.933,116.125],[-545.558,100.125],[-545.558,-106.5],[-531.933,-122.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":92.5,"s":[{"i":[[0,-9.113],[0,0],[7.042,0],[0,9.113],[0,0],[-7.042,0]],"o":[[0,0],[0,9.113],[-7.042,0],[0,0],[0,-9.113],[7.042,0]],"v":[[-566.367,-106.125],[-566.367,98.625],[-579.117,114.125],[-591.867,98.625],[-591.867,-106.125],[-579.117,-121.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0,-9.113],[0,0],[6.558,0],[0,9.113],[0,0],[-6.558,0]],"o":[[0,0],[0,9.113],[-6.558,0],[0,0],[0,-9.113],[6.558,0]],"v":[[-606.925,-105.75],[-606.925,97.125],[-618.8,112.125],[-630.675,97.125],[-630.675,-105.75],[-618.8,-120.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":94.166,"s":[{"i":[[0,-9.113],[0,0],[6.075,0],[0,9.113],[0,0],[-6.075,0]],"o":[[0,0],[0,9.113],[-6.075,0],[0,0],[0,-9.113],[6.075,0]],"v":[[-641.963,-105.375],[-641.963,95.625],[-652.963,110.125],[-663.963,95.625],[-663.963,-105.375],[-652.963,-119.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95,"s":[{"i":[[0,-9.113],[0,0],[5.592,0],[0,9.113],[0,0],[-5.592,0]],"o":[[0,0],[0,9.113],[-5.592,0],[0,0],[0,-9.113],[5.592,0]],"v":[[-671.062,-105],[-671.062,94.125],[-681.188,108.125],[-691.312,94.125],[-691.312,-105],[-681.188,-119]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95.834,"s":[{"i":[[0,-9.113],[0,0],[5.295,0],[0,9.113],[0,0],[-5.295,0]],"o":[[0,0],[0,9.113],[-5.295,0],[0,0],[0,-9.113],[5.295,0]],"v":[[-696.971,-104.5],[-696.971,92.5],[-706.558,106.25],[-716.146,92.5],[-716.146,-104.5],[-706.558,-118.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96.666,"s":[{"i":[[0,-9.113],[0,0],[4.998,0],[0,9.113],[0,0],[-4.998,0]],"o":[[0,0],[0,9.113],[-4.998,0],[0,0],[0,-9.113],[4.998,0]],"v":[[-718.192,-104],[-718.192,90.875],[-727.242,104.375],[-736.292,90.875],[-736.292,-104],[-727.242,-117.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0,-9.113],[0,0],[4.701,0],[0,9.113],[0,0],[-4.701,0]],"o":[[0,0],[0,9.113],[-4.701,0],[0,0],[0,-9.113],[4.701,0]],"v":[[-735.35,-103.5],[-735.35,89.25],[-743.862,102.5],[-752.375,89.25],[-752.375,-103.5],[-743.862,-116.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":98.334,"s":[{"i":[[0,-9.113],[0,0],[4.404,0],[0,9.113],[0,0],[-4.404,0]],"o":[[0,0],[0,9.113],[-4.404,0],[0,0],[0,-9.113],[4.404,0]],"v":[[-750.425,-103],[-750.425,87.625],[-758.4,100.625],[-766.375,87.625],[-766.375,-103],[-758.4,-116]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":99.166,"s":[{"i":[[0,-9.113],[0,0],[4.108,0],[0,9.113],[0,0],[-4.108,0]],"o":[[0,0],[0,9.113],[-4.108,0],[0,0],[0,-9.113],[4.108,0]],"v":[[-761.75,-102.5],[-761.75,86],[-769.188,98.75],[-776.625,86],[-776.625,-102.5],[-769.188,-115.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[0,-9.113],[0,0],[3.844,-0.015],[0.141,9.991],[0,0],[-4.51,0]],"o":[[0,0],[0,9.113],[-4.635,0.031],[0,0],[0.016,-9.897],[3.844,0]],"v":[[-771.312,-102.188],[-771.312,84.594],[-778.273,97.344],[-785.234,84.594],[-785.234,-102.188],[-778.273,-114.938]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[0,-9.113],[0,0],[3.581,-0.031],[0.281,10.869],[0,0],[-4.913,0]],"o":[[0,0],[0,9.113],[-5.163,0.062],[0,0],[0.031,-10.681],[3.581,0]],"v":[[-779.25,-101.875],[-779.25,83.188],[-785.734,95.938],[-792.219,83.188],[-792.219,-101.875],[-785.734,-114.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.666,"s":[{"i":[[0,-9.113],[0,0],[3.317,-0.046],[0.422,11.747],[0,0],[-5.316,0]],"o":[[0,0],[0,9.113],[-5.691,0.094],[0,0],[0.047,-11.466],[3.318,0]],"v":[[-786.125,-101.562],[-786.125,81.781],[-792.133,94.531],[-798.141,81.781],[-798.141,-101.562],[-792.133,-114.312]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":102.5,"s":[{"i":[[0,-9.113],[0,0],[3.054,-0.061],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-6.219,0.125],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-791.75,-101.25],[-791.75,80.375],[-797.281,93.125],[-802.812,80.375],[-802.812,-101.25],[-797.281,-114]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[0,-9.113],[0,0],[3.054,-0.07],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-6.51,0.153],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-796.934,-100.556],[-796.934,78.292],[-802.465,91.042],[-807.997,78.292],[-807.997,-100.556],[-802.465,-113.306]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.834,"s":[{"i":[[0,-9.113],[0,0],[3.054,-0.079],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-6.802,0.181],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-799.618,-99.861],[-799.618,76.208],[-805.149,88.958],[-810.681,76.208],[-810.681,-99.861],[-805.149,-112.611]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":108.334,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.092],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.24,0.222],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-800.61,-98.819],[-800.61,73.083],[-806.141,85.833],[-811.672,73.083],[-811.672,-98.819],[-806.141,-111.569]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":110,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-799.188,-98.125],[-799.188,71],[-804.719,83.75],[-814.636,70.875],[-814.636,-98.25],[-804.719,-110.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":119,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-787.944,-96.125],[-787.944,66.75],[-793.475,79.5],[-804.019,66.875],[-804.019,-96],[-793.475,-108.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":124,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-780.109,-96.579],[-780.109,65.77],[-785.64,78.355],[-796.184,65.566],[-796.184,-96.783],[-785.64,-108.836]],"c":true}]},{"t":128,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-779.207,-96.704],[-779.207,65.118],[-784.738,77.54],[-794.029,65.112],[-794.029,-96.71],[-784.738,-108.467]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[53.5,61],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":60,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"BUTTON_OUT_BOTTOM","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,157.219,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,25,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,-9.113],[0,0],[3.544,-0.062],[0,9.113],[0,0],[-1.905,0.228]],"o":[[0,0],[0,9.113],[-1.908,0.034],[0,0],[0,-9.113],[4.17,-0.5]],"v":[[688.299,-98],[688.299,65.125],[679.205,76.875],[675.75,65.375],[675.75,-97.75],[679.205,-108.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65,"s":[{"i":[[0,-9.113],[0,0],[4.532,-0.062],[0,9.113],[0,0],[-2.436,0.228]],"o":[[0,0],[0,9.113],[-2.44,0.034],[0,0],[0,-9.113],[5.332,-0.5]],"v":[[701.856,-97.875],[701.856,68.375],[689.293,80],[684.875,68.5],[684.875,-97.75],[689.293,-108.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70,"s":[{"i":[[0,-9.113],[0,0],[4.532,-0.062],[0,9.113],[0,0],[-2.436,0.228]],"o":[[0,0],[0,9.113],[-2.44,0.034],[0,0],[0,-9.113],[5.332,-0.5]],"v":[[709.974,-101.062],[709.974,76.125],[700.543,87.875],[696.125,76.375],[696.125,-100.812],[700.543,-111.688]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73,"s":[{"i":[[0,-9.113],[0,0],[5.113,-0.062],[0,9.113],[0,0],[-2.748,0.228]],"o":[[0,0],[0,9.113],[-2.753,0.034],[0,0],[0,-9.113],[6.016,-0.5]],"v":[[703.818,-102.625],[703.818,81.625],[692.568,93.125],[687.583,81.625],[687.583,-102.625],[692.568,-113.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":74.166,"s":[{"i":[[0,-9.113],[0,0],[5.694,-0.062],[0,9.113],[0,0],[-3.061,0.228]],"o":[[0,0],[0,9.113],[-3.065,0.034],[0,0],[0,-9.113],[6.699,-0.5]],"v":[[691.581,-103.125],[691.581,83.5],[686.03,95],[680.479,83.5],[680.479,-103.125],[686.03,-114]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,-9.113],[0,0],[6.275,-0.062],[0,9.113],[0,0],[-3.373,0.228]],"o":[[0,0],[0,9.113],[-3.378,0.034],[0,0],[0,-9.113],[7.383,-0.5]],"v":[[683.359,-103.625],[683.359,85.375],[677.242,96.875],[671.125,85.375],[671.125,-103.625],[677.242,-114.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75.834,"s":[{"i":[[0,-9.113],[0,0],[6.856,-0.062],[0,9.113],[0,0],[-3.685,0.228]],"o":[[0,0],[0,9.113],[-3.691,0.034],[0,0],[0,-9.113],[8.066,-0.5]],"v":[[672.305,-104.125],[672.305,87.25],[665.621,98.75],[658.938,87.25],[658.938,-104.125],[665.621,-115]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,-9.113],[0,0],[7.438,-0.062],[0,9.113],[0,0],[-3.997,0.228]],"o":[[0,0],[0,9.113],[-4.004,0.034],[0,0],[0,-9.113],[8.75,-0.5]],"v":[[657.5,-104.625],[657.5,89.125],[650.25,100.625],[643,89.125],[643,-104.625],[650.25,-115.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":77.5,"s":[{"i":[[0,-9.113],[0,0],[7.149,-0.047],[0,9.113],[0,0],[-4.569,0.171]],"o":[[0,0],[0,9.113],[-4.573,0.025],[0,0],[0,-9.113],[8.133,-0.375]],"v":[[637.562,-104.531],[637.562,90.531],[629.281,103.281],[621,90.531],[621,-104.531],[629.281,-116.812]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":78.334,"s":[{"i":[[0,-9.113],[0,0],[6.86,-0.031],[0,9.113],[0,0],[-5.14,0.114]],"o":[[0,0],[0,9.113],[-5.143,0.017],[0,0],[0,-9.113],[7.516,-0.25]],"v":[[612.625,-104.438],[612.625,91.938],[603.312,105.938],[594,91.938],[594,-104.438],[603.312,-118.125]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79.166,"s":[{"i":[[0,-9.113],[0,0],[6.571,-0.016],[0,9.113],[0,0],[-5.711,0.057]],"o":[[0,0],[0,9.113],[-5.713,0.008],[0,0],[0,-9.113],[6.899,-0.125]],"v":[[580.188,-104.094],[580.188,93.594],[569.844,108.844],[559.5,93.594],[559.5,-104.094],[569.844,-119.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[0,-9.113],[0,0],[6.282,0],[0,9.113],[0,0],[-6.282,0]],"o":[[0,0],[0,9.113],[-6.282,0],[0,0],[0,-9.113],[6.282,0]],"v":[[540.25,-103.75],[540.25,95.25],[528.875,111.75],[517.5,95.25],[517.5,-103.75],[528.875,-120.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80.834,"s":[{"i":[[0,-9.113],[0,0],[6.731,0],[0,9.113],[0,0],[-6.731,0]],"o":[[0,0],[0,9.113],[-6.731,0],[0,0],[0,-9.113],[6.731,0]],"v":[[491.25,-104.562],[491.25,97.688],[479.062,114.188],[466.875,97.688],[466.875,-104.562],[479.062,-121.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0,-9.113],[0,0],[7.18,0],[0,9.113],[0,0],[-7.18,0]],"o":[[0,0],[0,9.113],[-7.18,0],[0,0],[0,-9.113],[7.18,0]],"v":[[432.958,-105.375],[432.958,100.125],[419.958,116.625],[406.958,100.125],[406.958,-105.375],[419.958,-121.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.5,"s":[{"i":[[0,-9.113],[0,0],[7.628,0],[0,9.113],[0,0],[-7.628,0]],"o":[[0,0],[0,9.113],[-7.628,0],[0,0],[0,-9.113],[7.628,0]],"v":[[364.854,-106.188],[364.854,102.562],[351.042,119.062],[337.229,102.562],[337.229,-106.188],[351.042,-122.688]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[0,-9.113],[0,0],[8.077,0],[0,9.113],[0,0],[-8.077,0]],"o":[[0,0],[0,9.113],[-8.077,0],[0,0],[0,-9.113],[8.077,0]],"v":[[286.75,-107],[286.75,105],[272.125,121.5],[257.5,105],[257.5,-107],[272.125,-123.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[0,-9.113],[0,0],[8.33,0],[0,9.113],[0,0],[-8.33,0]],"o":[[0,0],[0,9.113],[-8.33,0],[0,0],[0,-9.113],[8.33,0]],"v":[[201.667,-107.5],[201.667,106.167],[186.583,122.667],[171.5,106.167],[171.5,-107.5],[186.583,-124]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85,"s":[{"i":[[0,-9.113],[0,0],[8.583,0],[0,9.113],[0,0],[-8.583,0]],"o":[[0,0],[0,9.113],[-8.583,0],[0,0],[0,-9.113],[8.583,0]],"v":[[110.333,-108],[110.333,107.333],[94.792,123.833],[79.25,107.333],[79.25,-108],[94.792,-124.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85.834,"s":[{"i":[[0,-9.113],[0,0],[8.837,0],[0,9.113],[0,0],[-8.837,0]],"o":[[0,0],[0,9.113],[-8.837,0],[0,0],[0,-9.113],[8.837,0]],"v":[[16.5,-108.5],[16.5,108.5],[0.5,125],[-15.5,108.5],[-15.5,-108.5],[0.5,-125]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0,-9.113],[0,0],[8.698,0],[0,9.113],[0,0],[-8.699,0]],"o":[[0,0],[0,9.113],[-8.699,0],[0,0],[0,-9.113],[8.698,0]],"v":[[-75.766,-108.229],[-75.766,107.667],[-91.516,124.167],[-107.266,107.667],[-107.266,-108.229],[-91.516,-124.729]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0,-9.113],[0,0],[8.56,0],[0,9.113],[0,0],[-8.56,0]],"o":[[0,0],[0,9.113],[-8.56,0],[0,0],[0,-9.113],[8.56,0]],"v":[[-166.781,-107.958],[-166.781,106.833],[-182.281,123.333],[-197.781,106.833],[-197.781,-107.958],[-182.281,-124.458]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88.334,"s":[{"i":[[0,-9.113],[0,0],[8.422,0],[0,9.113],[0,0],[-8.422,0]],"o":[[0,0],[0,9.113],[-8.422,0],[0,0],[0,-9.113],[8.422,0]],"v":[[-252.172,-107.688],[-252.172,106],[-267.422,122.5],[-282.672,106],[-282.672,-107.688],[-267.422,-124.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":89.166,"s":[{"i":[[0,-9.113],[0,0],[8.284,0],[0,9.113],[0,0],[-8.284,0]],"o":[[0,0],[0,9.113],[-8.284,0],[0,0],[0,-9.113],[8.284,0]],"v":[[-330.062,-107.417],[-330.062,105.167],[-345.062,121.667],[-360.062,105.167],[-360.062,-107.417],[-345.062,-123.917]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0,-9.113],[0,0],[8.146,0],[0,9.113],[0,0],[-8.146,0]],"o":[[0,0],[0,9.113],[-8.146,0],[0,0],[0,-9.113],[8.146,0]],"v":[[-400.781,-107.146],[-400.781,103.396],[-415.531,119.896],[-430.281,103.396],[-430.281,-107.146],[-415.531,-123.646]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90.834,"s":[{"i":[[0,-9.113],[0,0],[8.008,0],[0,9.113],[0,0],[-8.008,0]],"o":[[0,0],[0,9.113],[-8.008,0],[0,0],[0,-9.113],[8.008,0]],"v":[[-462.75,-106.875],[-462.75,101.625],[-477.25,118.125],[-491.75,101.625],[-491.75,-106.875],[-477.25,-123.375]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91.666,"s":[{"i":[[0,-9.113],[0,0],[7.525,0],[0,9.113],[0,0],[-7.525,0]],"o":[[0,0],[0,9.113],[-7.525,0],[0,0],[0,-9.113],[7.525,0]],"v":[[-518.308,-106.5],[-518.308,100.125],[-531.933,116.125],[-545.558,100.125],[-545.558,-106.5],[-531.933,-122.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":92.5,"s":[{"i":[[0,-9.113],[0,0],[7.042,0],[0,9.113],[0,0],[-7.042,0]],"o":[[0,0],[0,9.113],[-7.042,0],[0,0],[0,-9.113],[7.042,0]],"v":[[-566.367,-106.125],[-566.367,98.625],[-579.117,114.125],[-591.867,98.625],[-591.867,-106.125],[-579.117,-121.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0,-9.113],[0,0],[6.558,0],[0,9.113],[0,0],[-6.558,0]],"o":[[0,0],[0,9.113],[-6.558,0],[0,0],[0,-9.113],[6.558,0]],"v":[[-606.925,-105.75],[-606.925,97.125],[-618.8,112.125],[-630.675,97.125],[-630.675,-105.75],[-618.8,-120.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":94.166,"s":[{"i":[[0,-9.113],[0,0],[6.075,0],[0,9.113],[0,0],[-6.075,0]],"o":[[0,0],[0,9.113],[-6.075,0],[0,0],[0,-9.113],[6.075,0]],"v":[[-641.963,-105.375],[-641.963,95.625],[-652.963,110.125],[-663.963,95.625],[-663.963,-105.375],[-652.963,-119.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95,"s":[{"i":[[0,-9.113],[0,0],[5.592,0],[0,9.113],[0,0],[-5.592,0]],"o":[[0,0],[0,9.113],[-5.592,0],[0,0],[0,-9.113],[5.592,0]],"v":[[-671.062,-105],[-671.062,94.125],[-681.188,108.125],[-691.312,94.125],[-691.312,-105],[-681.188,-119]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95.834,"s":[{"i":[[0,-9.113],[0,0],[5.295,0],[0,9.113],[0,0],[-5.295,0]],"o":[[0,0],[0,9.113],[-5.295,0],[0,0],[0,-9.113],[5.295,0]],"v":[[-696.971,-104.5],[-696.971,92.5],[-706.558,106.25],[-716.146,92.5],[-716.146,-104.5],[-706.558,-118.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96.666,"s":[{"i":[[0,-9.113],[0,0],[4.998,0],[0,9.113],[0,0],[-4.998,0]],"o":[[0,0],[0,9.113],[-4.998,0],[0,0],[0,-9.113],[4.998,0]],"v":[[-718.192,-104],[-718.192,90.875],[-727.242,104.375],[-736.292,90.875],[-736.292,-104],[-727.242,-117.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0,-9.113],[0,0],[4.701,0],[0,9.113],[0,0],[-4.701,0]],"o":[[0,0],[0,9.113],[-4.701,0],[0,0],[0,-9.113],[4.701,0]],"v":[[-735.35,-103.5],[-735.35,89.25],[-743.862,102.5],[-752.375,89.25],[-752.375,-103.5],[-743.862,-116.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":98.334,"s":[{"i":[[0,-9.113],[0,0],[4.404,0],[0,9.113],[0,0],[-4.404,0]],"o":[[0,0],[0,9.113],[-4.404,0],[0,0],[0,-9.113],[4.404,0]],"v":[[-750.425,-103],[-750.425,87.625],[-758.4,100.625],[-766.375,87.625],[-766.375,-103],[-758.4,-116]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":99.166,"s":[{"i":[[0,-9.113],[0,0],[4.108,0],[0,9.113],[0,0],[-4.108,0]],"o":[[0,0],[0,9.113],[-4.108,0],[0,0],[0,-9.113],[4.108,0]],"v":[[-761.75,-102.5],[-761.75,86],[-769.188,98.75],[-776.625,86],[-776.625,-102.5],[-769.188,-115.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[0,-9.113],[0,0],[3.844,-0.015],[0.141,9.991],[0,0],[-4.51,0]],"o":[[0,0],[0,9.113],[-4.635,0.031],[0,0],[0.016,-9.897],[3.844,0]],"v":[[-771.312,-102.188],[-771.312,84.594],[-778.273,97.344],[-785.234,84.594],[-785.234,-102.188],[-778.273,-114.938]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[0,-9.113],[0,0],[3.581,-0.031],[0.281,10.869],[0,0],[-4.913,0]],"o":[[0,0],[0,9.113],[-5.163,0.062],[0,0],[0.031,-10.681],[3.581,0]],"v":[[-779.25,-101.875],[-779.25,83.188],[-785.734,95.938],[-792.219,83.188],[-792.219,-101.875],[-785.734,-114.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.666,"s":[{"i":[[0,-9.113],[0,0],[3.317,-0.046],[0.422,11.747],[0,0],[-5.316,0]],"o":[[0,0],[0,9.113],[-5.691,0.094],[0,0],[0.047,-11.466],[3.318,0]],"v":[[-786.125,-101.562],[-786.125,81.781],[-792.133,94.531],[-798.141,81.781],[-798.141,-101.562],[-792.133,-114.312]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":102.5,"s":[{"i":[[0,-9.113],[0,0],[3.054,-0.061],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-6.219,0.125],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-791.75,-101.25],[-791.75,80.375],[-797.281,93.125],[-802.812,80.375],[-802.812,-101.25],[-797.281,-114]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[0,-9.113],[0,0],[3.054,-0.07],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-6.51,0.153],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-796.934,-100.556],[-796.934,78.292],[-802.465,91.042],[-807.997,78.292],[-807.997,-100.556],[-802.465,-113.306]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.834,"s":[{"i":[[0,-9.113],[0,0],[3.054,-0.079],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-6.802,0.181],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-799.618,-99.861],[-799.618,76.208],[-805.149,88.958],[-810.681,76.208],[-810.681,-99.861],[-805.149,-112.611]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":108.334,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.092],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.24,0.222],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-800.61,-98.819],[-800.61,73.083],[-806.141,85.833],[-811.672,73.083],[-811.672,-98.819],[-806.141,-111.569]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":110,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-799.188,-98.125],[-799.188,71],[-804.719,83.75],[-814.636,70.875],[-814.636,-98.25],[-804.719,-110.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":119,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-787.944,-96.125],[-787.944,66.75],[-793.475,79.5],[-804.019,66.875],[-804.019,-96],[-793.475,-108.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":124,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-780.109,-96.579],[-780.109,65.77],[-785.64,78.355],[-796.184,65.566],[-796.184,-96.783],[-785.64,-108.836]],"c":true}]},{"t":128,"s":[{"i":[[0,-9.113],[0,0],[3.053,-0.101],[0.562,12.625],[0,0],[-5.719,0]],"o":[[0,0],[0,9.113],[-7.531,0.25],[0,0],[0.062,-12.25],[3.055,0]],"v":[[-779.207,-96.704],[-779.207,65.118],[-784.738,77.54],[-794.029,65.112],[-794.029,-96.71],[-784.738,-108.467]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[53.5,61],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":60,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"CENTER_LENS","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.013,149.919,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,-5.969],[5.969,0],[0,0],[0,5.969],[-5.969,0],[0,0]],"o":[[0,5.969],[0,0],[-5.969,0],[0,-5.969],[0,0],[5.969,0]],"v":[[21.408,0],[10.601,10.808],[-10.601,10.808],[-21.408,0],[-10.601,-10.808],[10.601,-10.808]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.5,"s":[{"i":[[-0.162,-5.954],[5.954,-0.162],[0,0],[0.162,5.954],[-5.954,0.162],[0,0]],"o":[[0.162,5.954],[0,0],[-5.954,0.162],[-0.162,-5.954],[0,0],[5.954,-0.162]],"v":[[23.471,-4.918],[12.899,6.54],[-8.812,6.806],[-19.793,-3.944],[-9.024,-15.178],[12.5,-15.603]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.166,"s":[{"i":[[-0.27,-5.944],[5.944,-0.27],[0,0],[0.27,5.944],[-5.944,0.27],[0,0]],"o":[[0.27,5.944],[0,0],[-5.944,0.27],[-0.27,-5.944],[0,0],[5.944,-0.27]],"v":[[24.429,-9.031],[14.014,2.862],[-8.037,3.305],[-19.132,-7.407],[-8.389,-18.924],[13.349,-19.633]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.666,"s":[{"i":[[-0.432,-5.929],[5.929,-0.432],[0,0],[0.432,5.929],[-5.929,0.432],[0,0]],"o":[[0.432,5.929],[0,0],[-5.929,0.432],[-0.432,-5.929],[0,0],[5.929,-0.432]],"v":[[24.667,-16.787],[14.488,-4.243],[-8.074,-3.534],[-19.342,-14.188],[-8.638,-26.132],[13.424,-27.266]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[-0.54,-5.92],[5.92,-0.54],[0,0],[0.54,5.92],[-5.92,0.54],[0,0]],"o":[[0.54,5.92],[0,0],[-5.92,0.54],[-0.54,-5.92],[0,0],[5.92,-0.54]],"v":[[23.575,-22.686],[13.553,-9.709],[-9.348,-8.823],[-20.732,-19.439],[-10.053,-31.666],[12.223,-33.083]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70,"s":[{"i":[[-0.648,-5.91],[5.91,-0.648],[0,0],[0.648,5.91],[-5.91,0.648],[0,0]],"o":[[0.648,5.91],[0,0],[-5.91,0.648],[-0.648,-5.91],[0,0],[5.91,-0.648]],"v":[[20.259,-30.049],[10.394,-16.638],[-13.048,-15.324],[-24.296,-25.801],[-13.644,-38.312],[9.173,-40.114]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":71.666,"s":[{"i":[[-0.756,-5.9],[5.9,-0.756],[0,0],[0.756,5.9],[-5.9,0.756],[0,0]],"o":[[0.756,5.9],[0,0],[-5.9,0.756],[-0.756,-5.9],[0,0],[5.9,-0.756]],"v":[[14.171,-38.307],[4.463,-24.462],[-19.518,-22.721],[-30.632,-33.06],[-20.005,-45.855],[3.351,-48.04]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":72.5,"s":[{"i":[[-0.81,-5.895],[5.895,-0.81],[0,0],[0.81,5.895],[-5.895,0.81],[0,0]],"o":[[0.81,5.895],[0,0],[-5.895,0.81],[-0.81,-5.895],[0,0],[5.895,-0.81]],"v":[[9.346,-43.279],[-0.283,-29.218],[-24.535,-27.263],[-35.581,-37.533],[-24.967,-50.47],[-1.34,-52.846]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73.334,"s":[{"i":[[-0.864,-5.89],[5.89,-0.864],[0,0],[0.864,5.89],[-5.89,0.864],[0,0]],"o":[[0.864,5.89],[0,0],[-5.89,0.864],[-0.864,-5.89],[0,0],[5.89,-0.864]],"v":[[3.001,-48.298],[-6.55,-34.019],[-30.497,-31.851],[-41.476,-42.052],[-30.875,-55.131],[-7.553,-57.699]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":74.166,"s":[{"i":[[-0.918,-5.885],[5.885,-0.918],[0,0],[0.918,5.885],[-5.885,0.918],[0,0]],"o":[[0.918,5.885],[0,0],[-5.885,0.918],[-0.918,-5.885],[0,0],[5.885,-0.918]],"v":[[-4.97,-53.817],[-14.443,-39.321],[-38.084,-36.939],[-48.996,-47.071],[-38.408,-60.292],[-15.391,-63.052]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[-0.972,-5.88],[5.88,-0.972],[0,0],[0.972,5.88],[-5.88,0.972],[0,0]],"o":[[0.972,5.88],[0,0],[-5.88,0.972],[-0.972,-5.88],[0,0],[5.88,-0.972]],"v":[[-14.941,-59.46],[-24.335,-44.748],[-47.671,-42.152],[-58.515,-52.215],[-47.94,-65.577],[-25.229,-68.529]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[-1.08,-5.87],[5.87,-1.08],[0,0],[1.08,5.87],[-5.87,1.08],[0,0]],"o":[[1.08,5.87],[0,0],[-5.87,1.08],[-1.08,-5.87],[0,0],[5.87,-1.08]],"v":[[-42.382,-72.123],[-51.619,-56.976],[-74.346,-53.953],[-85.055,-63.877],[-74.506,-77.524],[-52.404,-80.859]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":77.5,"s":[{"i":[[-0.856,-5.865],[5.839,-1.205],[0,0],[0.985,5.907],[-5.839,1.205],[0,0]],"o":[[0.855,5.886],[0,0],[-5.839,1.205],[-0.983,-5.883],[0,0],[5.839,-1.205]],"v":[[-61.785,-78.763],[-70.703,-63.449],[-91.979,-60.128],[-102.22,-70.048],[-92,-83.986],[-71.252,-87.688]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":78.334,"s":[{"i":[[-0.632,-5.86],[5.807,-1.33],[0,0],[0.89,5.944],[-5.807,1.33],[0,0]],"o":[[0.63,5.901],[0,0],[-5.807,1.33],[-0.886,-5.896],[0,0],[5.807,-1.33]],"v":[[-84.656,-85.779],[-93.256,-70.297],[-113.08,-66.679],[-122.854,-76.593],[-112.964,-90.823],[-93.568,-94.893]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79.166,"s":[{"i":[[-0.408,-5.856],[5.776,-1.455],[0,0],[0.796,5.981],[-5.776,1.455],[0,0]],"o":[[0.406,5.917],[0,0],[-5.776,1.455],[-0.79,-5.909],[0,0],[5.776,-1.455]],"v":[[-112.027,-92.795],[-120.308,-77.146],[-138.681,-73.229],[-147.987,-83.138],[-138.427,-97.659],[-120.384,-102.097]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[-0.184,-5.851],[5.744,-1.58],[0,0],[0.701,6.017],[-5.744,1.58],[0,0]],"o":[[0.181,5.932],[0,0],[-5.744,1.58],[-0.693,-5.922],[0,0],[5.744,-1.58]],"v":[[-144.7,-99.873],[-152.663,-84.056],[-169.585,-79.842],[-178.423,-89.745],[-169.193,-104.558],[-152.502,-109.364]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80.834,"s":[{"i":[[0.039,-5.846],[5.713,-1.705],[0,0],[0.606,6.054],[-5.713,1.705],[0,0]],"o":[[-0.044,5.947],[0,0],[-5.713,1.705],[-0.596,-5.935],[0,0],[5.713,-1.705]],"v":[[-181.936,-106.857],[-189.58,-90.873],[-205.051,-86.361],[-213.421,-96.259],[-204.521,-111.364],[-189.183,-116.536]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0.263,-5.841],[5.681,-1.83],[0,0],[0.511,6.091],[-5.681,1.83],[0,0]],"o":[[-0.269,5.963],[0,0],[-5.681,1.83],[-0.499,-5.948],[0,0],[5.682,-1.83]],"v":[[-225.421,-113.467],[-232.747,-97.315],[-246.767,-92.505],[-254.67,-102.398],[-246.098,-117.794],[-232.114,-123.334]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.5,"s":[{"i":[[0.201,-5.842],[4.849,-1.973],[0,0],[0.428,5.773],[-4.511,1.767],[0,0]],"o":[[-0.205,5.947],[0,0],[-4.849,1.973],[-0.429,-5.935],[0,0],[4.849,-1.973]],"v":[[-275.671,-118.903],[-281.694,-102.971],[-292.741,-98.418],[-299.149,-108.831],[-292.426,-123.38],[-281.329,-128.511]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[0.138,-5.843],[4.017,-2.117],[0,0],[0.345,5.456],[-3.34,1.705],[0,0]],"o":[[-0.141,5.931],[0,0],[-4.017,2.117],[-0.359,-5.922],[0,0],[4.017,-2.117]],"v":[[-331.129,-123.089],[-335.849,-107.376],[-343.923,-103.082],[-348.837,-114.013],[-343.962,-127.716],[-335.753,-132.438]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[0.075,-5.844],[3.184,-2.261],[0,0],[0.262,5.138],[-2.169,1.643],[0,0]],"o":[[-0.077,5.915],[0,0],[-3.184,2.261],[-0.289,-5.909],[0,0],[4.042,-3.442]],"v":[[-389.712,-125.963],[-393.129,-110.469],[-398.605,-106.433],[-402.024,-117.883],[-398.998,-130.74],[-393.301,-136.302]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85,"s":[{"i":[[0.012,-5.845],[2.352,-2.405],[0,0],[0.179,4.821],[-0.999,1.58],[0,0]],"o":[[-0.012,5.899],[0,0],[-2.352,2.405],[-0.219,-5.895],[0,0],[4.066,-4.767]],"v":[[-451.421,-127.712],[-453.534,-112.437],[-455.663,-108.66],[-457.587,-120.628],[-456.41,-132.638],[-453.975,-136.541]],"c":true}]},{"t":85.833984375,"s":[{"i":[[0.012,-5.845],[0.626,-2.62],[0,0],[0.179,4.821],[-0.999,1.58],[0,0]],"o":[[-0.012,5.899],[0,0],[-1.245,-2.898],[-0.219,-5.895],[0,0],[0.566,-0.017]],"v":[[-512.671,-125.712],[-513.534,-115.437],[-514.163,-115.66],[-514.337,-122.878],[-513.66,-133.888],[-512.975,-134.041]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[509.408,-610.192],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":87,"st":60,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"FRONT_LENS 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[-1.125,-0.688],[0,-10.77],[3.375,0.312],[0,10.77]],"o":[[2.027,1.239],[0,10.77],[-1.122,-0.104],[0,-10.77]],"v":[[-333.875,52.938],[-332.25,68.688],[-333.875,88.188],[-335.5,68.688]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88.334,"s":[{"i":[[-1.661,-0.597],[0,-10.77],[3.518,0.277],[0,10.77]],"o":[[2.541,1.071],[0,10.77],[-1.622,-0.098],[0,-10.77]],"v":[[-304.741,51.121],[-301.683,67.085],[-304.277,86.335],[-307.339,67.121]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":89.166,"s":[{"i":[[-2.197,-0.507],[0,-10.77],[3.661,0.241],[0,10.77]],"o":[[3.055,0.903],[0,10.77],[-2.123,-0.093],[0,-10.77]],"v":[[-277.357,49.304],[-272.866,65.482],[-276.429,84.482],[-280.929,65.554]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90.834,"s":[{"i":[[-3.27,-0.326],[0,-10.77],[3.946,0.17],[0,10.77]],"o":[[4.083,0.567],[0,10.77],[-3.124,-0.082],[0,-10.77]],"v":[[-227.089,45.67],[-219.732,62.277],[-225.232,80.777],[-232.607,62.42]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91.666,"s":[{"i":[[-3.806,-0.235],[0,-10.77],[4.089,0.134],[0,10.77]],"o":[[4.597,0.399],[0,10.77],[-3.624,-0.077],[0,-10.77]],"v":[[-205.132,43.467],[-196.561,60.289],[-202.811,78.539],[-211.478,60.467]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":92.5,"s":[{"i":[[-4.342,-0.145],[0,-10.77],[4.232,0.098],[0,10.77]],"o":[[5.111,0.231],[0,10.77],[-4.125,-0.071],[0,-10.77]],"v":[[-185.301,41.265],[-175.515,58.301],[-182.515,76.301],[-192.473,58.515]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[-4.878,-0.054],[0,-10.77],[4.375,0.062],[0,10.77]],"o":[[5.625,0.062],[0,10.77],[-4.625,-0.066],[0,-10.77]],"v":[[-167.125,38.688],[-156.125,55.938],[-163.875,73.688],[-175.125,56.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":94.166,"s":[{"i":[[-5.277,0],[-0.118,-10.643],[4.875,0.012],[-0.062,10.649]],"o":[[5.85,0.012],[0.088,10.399],[-5.238,-0.009],[0.07,-10.767]],"v":[[-150.531,36.3],[-139.006,53.575],[-147.306,71.35],[-159.156,53.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95,"s":[{"i":[[-5.675,0.055],[-0.236,-10.516],[5.375,-0.037],[-0.125,10.528]],"o":[[6.075,-0.038],[0.175,10.028],[-5.852,0.048],[0.14,-10.765]],"v":[[-135.188,33.788],[-123.137,51.088],[-131.988,68.887],[-144.438,51.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95.834,"s":[{"i":[[-6.073,0.11],[-0.353,-10.39],[5.875,-0.087],[-0.188,10.407]],"o":[[6.3,-0.087],[0.262,9.657],[-6.465,0.104],[0.211,-10.763]],"v":[[-121.771,31.306],[-109.196,48.631],[-118.596,66.456],[-131.646,48.656]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96.666,"s":[{"i":[[-6.472,0.164],[-0.471,-10.263],[6.375,-0.138],[-0.25,10.287]],"o":[[6.525,-0.137],[0.35,9.287],[-7.078,0.161],[0.281,-10.76]],"v":[[-109.104,28.825],[-96.004,46.175],[-105.954,64.025],[-119.604,46.125]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[-6.87,0.219],[-0.589,-10.137],[6.875,-0.188],[-0.312,10.166]],"o":[[6.75,-0.188],[0.438,8.916],[-7.691,0.218],[0.351,-10.758]],"v":[[-97.75,26.438],[-84.125,43.812],[-94.625,61.688],[-108.875,43.688]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":98.334,"s":[{"i":[[-7.268,0.274],[-0.706,-10.01],[7.375,-0.238],[-0.375,10.045]],"o":[[6.975,-0.238],[0.525,8.545],[-8.305,0.275],[0.421,-10.756]],"v":[[-87.767,24.188],[-73.617,41.588],[-84.667,59.488],[-99.517,41.387]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[-8.065,0.383],[-0.942,-9.757],[8.375,-0.338],[-0.5,9.804]],"o":[[7.425,-0.337],[0.7,7.804],[-9.531,0.388],[0.562,-10.751]],"v":[[-70.425,19.688],[-55.225,37.137],[-67.375,55.088],[-83.425,36.788]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.666,"s":[{"i":[[-8.862,0.492],[-1.177,-9.504],[9.375,-0.438],[-0.625,9.562]],"o":[[7.875,-0.438],[0.875,7.062],[-10.758,0.502],[0.702,-10.747]],"v":[[-56.375,15.188],[-40.125,32.688],[-53.375,50.688],[-70.625,32.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":103.334,"s":[{"i":[[-9.071,0.394],[-0.942,-9.584],[9.481,-0.35],[-0.5,9.631]],"o":[[8.281,-0.35],[0.7,7.631],[-10.588,0.402],[0.562,-10.579]],"v":[[-45.213,11.238],[-28.625,28.887],[-42.775,47.012],[-60.2,28.488]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105,"s":[{"i":[[-9.28,0.295],[-0.706,-9.665],[9.588,-0.262],[-0.375,9.7]],"o":[[8.688,-0.262],[0.525,8.2],[-10.417,0.301],[0.421,-10.411]],"v":[[-36.05,7.496],[-19.125,25.296],[-34.175,43.546],[-51.775,24.996]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.834,"s":[{"i":[[-9.384,0.246],[-0.589,-9.705],[9.641,-0.219],[-0.312,9.735]],"o":[[8.891,-0.219],[0.438,8.485],[-10.332,0.251],[0.351,-10.327]],"v":[[-31.875,5.625],[-14.781,23.5],[-30.281,41.812],[-47.969,23.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[-9.593,0.148],[-0.353,-9.786],[9.747,-0.131],[-0.188,9.803]],"o":[[9.297,-0.131],[0.262,9.053],[-10.162,0.151],[0.211,-10.159]],"v":[[-25.337,2.55],[-7.906,20.575],[-24.306,39.012],[-42.169,20.425]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":110,"s":[{"i":[[-9.907,0],[0,-9.907],[9.907,0],[0,9.907]],"o":[[9.907,0],[0,9.907],[-9.907,0],[0,-9.907]],"v":[[-17.125,-2.062],[0.812,16.188],[-16.938,34.812],[-35.062,16.188]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":114.166,"s":[{"i":[[-10.77,0],[0,-10.77],[10.77,0],[0,10.77]],"o":[[10.77,0],[0,10.77],[-10.77,0],[0,-10.77]],"v":[[-8.781,-9.156],[10.719,10.344],[-8.781,29.844],[-28.281,10.344]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118.334,"s":[{"i":[[-10.77,0],[0,-10.77],[10.77,0],[0,10.77]],"o":[[10.77,0],[0,10.77],[-10.77,0],[0,-10.77]],"v":[[-4.188,-13.375],[15.312,6.125],[-4.188,25.625],[-23.688,6.125]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":122.5,"s":[{"i":[[-10.77,0],[0,-10.77],[10.77,0],[0,10.77]],"o":[[10.77,0],[0,10.77],[-10.77,0],[0,-10.77]],"v":[[-1.562,-16.438],[17.938,3.062],[-1.562,22.562],[-21.062,3.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126.666,"s":[{"i":[[-10.77,0],[0,-10.77],[10.77,0],[0,10.77]],"o":[[10.77,0],[0,10.77],[-10.77,0],[0,-10.77]],"v":[[-0.188,-18.25],[19.312,1.25],[-0.188,20.75],[-19.688,1.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":130.834,"s":[{"i":[[-10.77,0],[0,-10.77],[10.77,0],[0,10.77]],"o":[[10.77,0],[0,10.77],[-10.77,0],[0,-10.77]],"v":[[0.5,-19.469],[20,0.031],[0.5,19.531],[-19,0.031]],"c":true}]},{"t":135,"s":[{"i":[[-10.77,0],[0,-10.77],[10.77,0],[0,10.77]],"o":[[10.77,0],[0,10.77],[-10.77,0],[0,-10.77]],"v":[[0.688,-20.062],[20.188,-0.562],[0.688,18.938],[-18.812,-0.562]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[385.5,-561.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":87,"op":342,"st":60,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"CENTER_SCREEN 3","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[699,-539],[699,539],[653,585],[-0.999,585],[-653,585],[-699,539],[-699,-539],[-653,-585],[1,-585],[653,-585]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.166,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[707,-547],[707,547],[661,593],[-0.999,585],[-639.273,577],[-685.273,531],[-685.273,-527],[-639.273,-573],[1,-585],[661,-593]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[715,-563],[715,567],[669,613],[-0.999,585],[-617.545,561],[-663.545,515],[-663.545,-511],[-617.545,-557],[1,-585],[669,-609]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70.834,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[709,-577.4],[709,579],[663,625],[-0.999,585],[-587.709,551.4],[-636.709,505.4],[-636.709,-501.4],[-587.709,-547.4],[1,-585],[663,-623.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":72.5,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[705,-587],[705,587],[659,633],[-0.999,585],[-567.818,545],[-613.818,499],[-613.818,-495],[-567.818,-541],[1,-585],[659,-633]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73.334,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[697.4,-593.4],[697.4,595],[651.4,641],[-0.999,585],[-553.873,539.4],[-599.873,493.4],[-599.873,-490.2],[-553.873,-536.2],[1,-585],[651.4,-639.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":74.166,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[693.8,-599.8],[693.8,603],[647.8,649],[-0.999,585],[-537.927,533.8],[-583.927,487.8],[-583.927,-485.4],[-537.927,-531.4],[1,-585],[647.8,-645.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[678.2,-606.2],[678.2,611],[632.2,657],[-0.999,585],[-519.982,528.2],[-565.982,482.2],[-565.982,-480.6],[-519.982,-526.6],[1,-585],[632.2,-652.2]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75.834,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[666.6,-612.6],[666.6,619],[620.6,665],[-0.999,585],[-499.036,522.6],[-545.036,476.6],[-545.036,-475.8],[-499.036,-521.8],[1,-585],[620.6,-658.6]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[647,-619],[647,627],[601,673],[-0.999,585],[-478.091,517],[-524.091,471],[-524.091,-471],[-478.091,-517],[1,-585],[601,-665]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":78.334,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.223,2.5],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-22.441,-1.8],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[600.891,-638.2],[600.891,649.545],[561.618,691.182],[-5.908,586.273],[-428.856,507],[-467.174,466.273],[-467.174,-463],[-420.674,-508.5],[1,-585.6],[554.891,-684.2]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79.166,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.132,3.75],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-20.96,-2.7],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[561.836,-647.8],[561.836,660.818],[525.927,700.273],[-8.363,586.909],[-398.739,502],[-433.216,463.909],[-433.216,-459],[-386.466,-504.25],[1,-585.9],[515.836,-693.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.041,5],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-19.478,-3.6],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[522.782,-657.4],[522.782,672.091],[490.236,709.364],[-10.817,587.546],[-368.621,497],[-399.258,461.546],[-399.258,-455],[-352.258,-500],[1,-586.2],[476.782,-703.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80.834,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-24.95,6.25],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-17.996,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[471.727,-667],[471.727,683.364],[442.545,718.455],[-13.272,588.182],[-332.504,492],[-359.3,459.182],[-359.3,-451],[-312.05,-495.75],[1,-586.5],[425.727,-713]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0.129,-24.588],[0,0],[21.663,1.508],[0,0],[0,0],[0.008,23.224],[0,0],[-21.2,5.875],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-15.329,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[21.8,-2.083]],"v":[[412.352,-679.333],[412.352,694.197],[387.295,726.538],[-16.188,588.015],[-289.754,488.25],[-312.675,457.182],[-312.675,-449],[-272.55,-491.375],[-4.583,-587],[372.894,-720.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.5,"s":[{"i":[[0.258,-23.77],[0,0],[17.922,3.015],[0,0],[0,0],[0.017,21.043],[0,0],[-17.45,5.5],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-12.663,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[18.194,-4.167]],"v":[[344.977,-691.667],[344.977,705.03],[324.045,734.621],[-19.105,587.849],[-247.004,484.5],[-266.05,455.182],[-266.05,-447],[-233.05,-487],[-10.166,-587.5],[312.06,-728.333]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[0.386,-22.953],[0,0],[14.18,4.523],[0,0],[0,0],[0.025,18.862],[0,0],[-13.7,5.125],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-9.996,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[14.589,-6.25]],"v":[[269.602,-704],[269.602,715.864],[252.795,742.705],[-22.022,587.682],[-204.254,480.75],[-219.425,453.182],[-219.425,-445],[-193.55,-482.625],[-15.75,-588],[243.227,-736]],"c":true}]},{"t":85.833984375,"s":[{"i":[[0.773,-20.5],[0,0],[2.955,9.045],[0,0],[0,0],[0.05,12.318],[0,0],[-2.45,4],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-1.996,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[3.773,-12.5]],"v":[[13.477,-707],[13.477,713.364],[9.045,731.955],[-30.772,587.182],[-58.004,481.5],[-61.55,459.182],[-61.55,-451],[-57.05,-481.5],[-32.5,-581.5],[6.727,-725]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-3,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":87,"st":60,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Figure 10","tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72.5,"s":[100]},{"t":80.833984375,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[206.959,124.54,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[206.959,124.54,0],"to":[-1.125,0,0],"ti":[1.125,0,0]},{"t":85.833984375,"s":[200.209,124.54,0]}],"ix":2,"l":2},"a":{"a":0,"k":[270.209,145.54,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.55,0.55,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,-0.47]},"t":60,"s":[125,125,100]},{"t":110,"s":[125,125,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,0],[-1.939,-1.387],[6.061,-1.3],[0.907,1.308]],"o":[[1.066,0.711],[2.423,1.734],[-4.85,1.04],[0,0]],"v":[[-0.582,-6.237],[5.035,-2.37],[2.01,5.979],[-6.77,3.354]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[0,0],[-1.877,-1.382],[5.87,-1.295],[0.878,1.303]],"o":[[1.032,0.708],[2.346,1.727],[-4.697,1.036],[0,0]],"v":[[-0.131,-5.771],[5.309,-1.919],[2.379,6.397],[-6.124,3.782]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,0],[-1.627,-1.365],[5.086,-1.278],[0.761,1.287]],"o":[[0.894,0.699],[2.033,1.706],[-4.07,1.023],[0,0]],"v":[[1.024,-4.856],[5.738,-1.053],[3.2,7.16],[-4.168,4.578]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0,0],[-0.79,-1.365],[2.613,-0.951],[0.598,1.216]],"o":[[0.434,0.699],[0.987,1.706],[-1.617,0.588],[0,0]],"v":[[-0.98,-5.389],[1.308,-1.586],[-0.339,6.331],[-4.212,3.985]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[0,0],[-0.387,-1.365],[1.28,-0.951],[0.293,1.216]],"o":[[0.213,0.699],[0.483,1.706],[-0.792,0.588],[0,0]],"v":[[-1.492,-5.389],[-0.371,-1.586],[-1.178,6.331],[-3.075,3.985]],"c":false}]},{"t":85.833984375,"s":[{"i":[[0,0],[-0.123,-1.365],[0.408,-0.951],[0.093,1.216]],"o":[[0.068,0.699],[0.154,1.706],[-0.253,0.588],[0,0]],"v":[[-2,-5.389],[-1.642,-1.586],[-1.9,6.331],[-2.505,3.985]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.596078455448,0.321568638086,0.239215686917,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.12,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[272.026,152.086],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[-3.926,7.277],[-8.848,0],[-3.783,2.669],[18.309,-0.059],[0.81,-15.17],[-4.916,0]],"o":[[3.926,7.277],[4.982,0],[-0.845,-15.213],[-18.267,0.059],[3.755,2.604],[8.848,0]],"v":[[-0.106,3.616],[20.359,15.839],[33.729,11.589],[-0.12,-15.891],[-33.793,11.7],[-20.571,15.839]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[-3.803,7.248],[-8.57,0],[-3.664,2.658],[17.733,-0.059],[0.785,-15.11],[-4.761,0]],"o":[[3.803,7.248],[4.825,0],[-0.819,-15.153],[-17.692,0.058],[3.637,2.594],[8.57,0]],"v":[[0.379,4.215],[20.2,16.39],[33.149,12.156],[0.365,-15.216],[-32.248,12.267],[-19.442,16.39]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[-3.295,7.158],[-7.426,0],[-3.175,2.625],[15.365,-0.058],[0.472,-17.15],[-4.125,0]],"o":[[3.295,7.158],[4.181,0],[-0.823,-14.189],[-15.33,0.058],[3.151,2.562],[7.426,0]],"v":[[-0.465,5.074],[17.661,15.91],[29.594,11.253],[1.662,-15.066],[-26.597,13.501],[-16.213,17.098]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[-1.951,7.158],[-4.397,0],[-1.88,2.625],[9.099,-0.058],[0.279,-17.15],[-2.443,0]],"o":[[1.951,7.158],[2.476,0],[-0.487,-14.189],[-9.078,0.058],[1.866,2.562],[4.397,0]],"v":[[-0.259,5.074],[10.475,15.91],[17.542,11.253],[1.001,-15.066],[-15.734,13.501],[-9.585,17.098]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[-0.956,7.158],[-2.154,0],[-0.921,2.625],[4.456,-0.058],[0.137,-17.15],[-1.196,0]],"o":[[0.956,7.158],[1.213,0],[-0.239,-14.189],[-4.446,0.058],[0.914,2.562],[2.154,0]],"v":[[-0.818,5.074],[4.203,15.91],[8.137,11.253],[0.036,-15.066],[-7.924,13.501],[-5.622,16.388]],"c":true}]},{"t":85.833984375,"s":[{"i":[[-0.305,7.158],[-0.687,0],[-0.294,2.625],[1.422,-0.058],[0.044,-17.15],[-0.382,0]],"o":[[0.305,7.158],[0.387,0],[-0.076,-14.189],[-1.419,0.058],[0.292,2.562],[0.687,0]],"v":[[-0.725,5.074],[0.877,15.91],[2.132,11.253],[-0.453,-15.066],[-2.992,13.501],[-2.258,16.388]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,9.805],[9.805,0],[0,-9.805],[-9.805,0]],"o":[[0,-9.805],[-9.805,0],[0,9.805],[9.805,0]],"v":[[-6.59,-22.526],[-24.345,-40.281],[-42.099,-22.526],[-24.345,-4.772]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[0,9.767],[9.497,0],[0,-9.767],[-9.497,0]],"o":[[0,-9.767],[-9.497,0],[0,9.767],[9.497,0]],"v":[[-5.901,-21.825],[-23.097,-39.51],[-40.292,-21.825],[-23.097,-4.14]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,9.646],[7.896,0],[0,-9.646],[-7.896,0]],"o":[[0,-9.646],[-7.896,0],[0,9.646],[7.896,0]],"v":[[-4.974,-20.167],[-18.558,-37.632],[-33.567,-20.167],[-19.984,-2.94]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0,9.646],[4.638,0],[0,-9.646],[-4.639,0]],"o":[[0,-9.646],[-4.638,0],[0,9.646],[4.639,0]],"v":[[-2.828,-18.982],[-10.807,-36.448],[-19.625,-18.982],[-11.645,-1.755]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[0,9.435],[2.13,0],[0,-9.435],[-2.131,0]],"o":[[0,-9.435],[-2.13,0],[0,9.435],[2.131,0]],"v":[[-2.351,-18.418],[-6.016,-35.501],[-10.066,-18.418],[-6.401,-1.568]],"c":true}]},{"t":85.833984375,"s":[{"i":[[0,9.435],[0.68,0],[0,-9.435],[-0.68,0]],"o":[[0,-9.435],[-0.68,0],[0,9.435],[0.68,0]],"v":[[-1.214,-18.418],[-2.384,-35.501],[-3.676,-18.418],[-2.506,-1.568]],"c":true}]}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337254911661,0.23137255013,0.129411771894,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.47,108.276],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hair","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[-7.446,13.962],[0,0],[0,0],[-0.313,2.62],[0.015,4.351],[0,0],[-18.83,0.06],[-0.051,-15.806],[0,0],[-0.49,-2.669],[-1.873,-4.352],[-0.89,-3.988],[0,-4.307],[8.014,-5.508],[12.335,-0.04],[8.035,5.309],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.222,-4.479],[0.309,-2.598],[0,0],[-0.051,-15.806],[18.83,-0.06],[0,0],[0.013,4.276],[0.495,2.702],[3.604,8.387],[0.884,3.962],[0,7.459],[-7.997,5.495],[-12.35,0.04],[-8.04,-5.313],[0,0],[0,-6.072]],"v":[[-36.861,-4.598],[-36.804,-4.703],[-36.772,-4.819],[-34.61,-14.535],[-34.324,-24.06],[-34.324,-24.128],[-0.614,-53.129],[33.278,-24.345],[33.278,-24.252],[33.789,-14.641],[37.134,-4.922],[43.41,12.489],[44.307,23.718],[31.53,43.997],[0.092,53.129],[-31.449,44.589],[-44.307,24.009],[-44.307,23.977]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[-7.211,13.907],[0,0],[0,0],[-0.301,2.61],[0.014,4.334],[0,0],[-18.237,0.06],[-0.049,-15.744],[0,0],[-0.473,-2.659],[-1.812,-4.336],[-0.861,-3.972],[0,-4.29],[7.763,-5.486],[11.947,-0.04],[7.782,5.289],[0,7.963],[0,0]],"o":[[0,0],[0,0],[1.183,-4.461],[0.299,-2.588],[0,0],[-0.049,-15.745],[18.237,-0.06],[0,0],[0.012,4.259],[0.479,2.691],[3.491,8.354],[0.856,3.947],[0,7.43],[-7.746,5.474],[-11.961,0.04],[-7.787,-5.292],[0,0],[0,-6.048]],"v":[[-35.236,-4.113],[-35.18,-4.218],[-35.15,-4.333],[-33.055,-14.011],[-32.779,-23.499],[-32.779,-23.567],[-0.13,-52.454],[32.696,-23.783],[32.696,-23.69],[33.191,-14.117],[36.43,-4.435],[42.509,12.908],[43.377,24.093],[31.002,44.292],[0.554,53.389],[-29.994,44.882],[-42.447,24.383],[-42.447,24.35]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[-6.248,13.734],[0,0],[0,0],[-0.261,2.577],[0.012,4.28],[0,0],[-15.802,0.059],[-0.043,-15.549],[0,0],[-0.41,-2.626],[-1.57,-4.282],[-0.746,-3.923],[0,-4.237],[6.726,-5.417],[10.352,-0.039],[6.743,5.223],[0,7.864],[0,0]],"o":[[0,0],[0,0],[1.025,-4.406],[0.259,-2.556],[0,0],[-0.237,-16.662],[15.802,-0.059],[0,0],[0.011,4.206],[0.415,2.658],[3.025,8.25],[0.742,3.898],[0,7.337],[-6.712,5.406],[-10.364,0.039],[-6.747,-5.226],[0,0],[0,-5.973]],"v":[[-29.256,-3.138],[-29.208,-3.242],[-29.181,-3.355],[-27.366,-12.913],[-27.127,-22.283],[-27.127,-22.35],[1.163,-52.304],[29.606,-22.564],[29.606,-22.471],[30.035,-13.018],[32.842,-3.456],[38.109,13.671],[38.861,24.717],[28.139,44.665],[2.706,53.173],[-23.764,44.772],[-34.554,24.528],[-34.554,24.496]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[-3.7,13.734],[0,0],[0,0],[-0.155,2.577],[0.007,4.28],[0,0],[-9.358,0.059],[-0.025,-15.549],[0,0],[-0.243,-2.626],[-0.93,-4.282],[-0.442,-3.923],[0,-4.237],[3.983,-5.417],[6.13,-0.039],[3.993,5.223],[0,7.864],[0,0]],"o":[[0,0],[0,0],[0.607,-4.406],[0.153,-2.556],[0,0],[-0.14,-16.662],[9.358,-0.059],[0,0],[0.006,4.206],[0.246,2.658],[1.791,8.25],[0.439,3.898],[0,7.337],[-3.975,5.406],[-6.138,0.039],[-3.996,-5.226],[0,0],[0,-5.973]],"v":[[-17.523,-3.138],[-17.495,-3.242],[-17.479,-3.355],[-16.405,-12.913],[-16.263,-22.283],[-16.263,-22.35],[0.491,-52.304],[17.334,-22.564],[17.334,-22.471],[17.588,-13.018],[19.251,-3.456],[22.37,13.671],[22.815,24.717],[16.465,44.665],[1.404,53.173],[-14.271,44.772],[-20.661,24.528],[-20.661,24.496]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[-1.812,13.734],[0,0],[0,0],[-0.076,2.577],[0.004,4.28],[0,0],[-4.583,0.059],[-0.012,-15.549],[0,0],[-0.119,-2.626],[-0.455,-4.282],[-0.216,-3.923],[0,-4.237],[1.951,-5.417],[3.002,-0.039],[1.956,5.223],[0,7.864],[0,0]],"o":[[0,0],[0,0],[0.297,-4.406],[0.075,-2.556],[0,0],[-0.069,-16.662],[4.583,-0.059],[0,0],[0.003,4.206],[0.12,2.658],[0.877,8.25],[0.215,3.898],[0,7.337],[-1.947,5.406],[-3.006,0.039],[-1.957,-5.226],[0,0],[0,-5.973]],"v":[[-9.069,-3.138],[-9.055,-3.242],[-9.047,-3.355],[-8.521,-12.913],[-8.451,-22.283],[-8.451,-22.35],[-0.482,-52.304],[8.004,-22.564],[8.004,-22.471],[8.128,-13.018],[8.469,-3.22],[9.997,13.434],[10.215,24.48],[7.578,44.665],[0.202,53.173],[-7.476,44.772],[-10.605,24.528],[-10.605,24.496]],"c":true}]},{"t":85.833984375,"s":[{"i":[[-0.578,13.734],[0,0],[0,0],[-0.024,2.577],[0.001,4.28],[0,0],[-1.462,0.059],[-0.004,-15.549],[0,0],[-0.038,-2.626],[-0.145,-4.282],[-0.069,-3.923],[0,-4.237],[0.622,-5.417],[0.958,-0.039],[0.624,5.223],[0,7.864],[0,0]],"o":[[0,0],[0,0],[0.095,-4.406],[0.024,-2.556],[0,0],[-0.022,-16.662],[1.462,-0.059],[0,0],[0.001,4.206],[0.038,2.658],[0.28,8.25],[0.069,3.898],[0,7.337],[-0.621,5.406],[-0.959,0.039],[-0.624,-5.226],[0,0],[0,-5.973]],"v":[[-3.716,-3.138],[-3.711,-3.242],[-3.709,-3.355],[-3.541,-12.913],[-3.519,-22.283],[-3.519,-22.35],[-0.976,-52.304],[1.731,-22.564],[1.731,-22.471],[1.771,-13.018],[1.88,-3.22],[2.367,13.434],[2.437,24.48],[1.596,44.665],[-0.758,53.173],[-3.207,44.772],[-4.206,24.528],[-4.206,24.496]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[4.598,1.656],[-2.64,7.412],[-4.598,-1.656],[2.64,-7.412]],"o":[[-4.6,-1.657],[2.64,-7.412],[4.6,1.657],[-2.64,7.412]],"v":[[30.635,-0.09],[27.088,-16.51],[40.195,-26.931],[43.742,-10.511]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[4.453,1.649],[-2.557,7.383],[-4.453,-1.649],[2.557,-7.383]],"o":[[-4.455,-1.65],[2.557,-7.383],[4.455,1.65],[-2.557,7.383]],"v":[[30.136,0.377],[26.7,-15.979],[39.395,-26.359],[42.831,-10.003]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[3.958,1.629],[-2.273,7.291],[-3.958,-1.629],[2.273,-7.291]],"o":[[-3.96,-1.63],[2.273,-7.291],[3.96,1.63],[-2.273,7.291]],"v":[[26.809,-1.08],[23.755,-17.233],[35.038,-27.484],[38.092,-11.332]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[2.344,1.629],[-1.346,7.291],[-2.344,-1.629],[1.346,-7.291]],"o":[[-2.345,-1.63],[1.346,-7.291],[2.345,1.63],[-1.346,7.291]],"v":[[15.441,-1.791],[13.633,-17.943],[20.314,-28.195],[22.123,-12.042]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[1.148,1.629],[-0.659,7.291],[-1.148,-1.629],[0.659,-7.291]],"o":[[-1.149,-1.63],[0.659,-7.291],[1.148,1.63],[-0.659,7.291]],"v":[[7.076,-1.791],[6.191,-17.943],[9.463,-28.195],[10.349,-12.042]],"c":true}]},{"t":85.833984375,"s":[{"i":[[0.366,1.629],[-0.21,7.291],[-0.366,-1.629],[0.21,-7.291]],"o":[[-0.366,-1.63],[0.21,-7.291],[0.366,1.63],[-0.21,7.291]],"v":[[1.436,-1.791],[1.153,-17.943],[2.197,-28.195],[2.48,-12.042]],"c":true}]}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[4.598,-1.656],[2.64,7.412],[-4.598,1.656],[-2.64,-7.412]],"o":[[-4.6,1.657],[-2.64,-7.412],[4.6,-1.657],[2.64,7.412]],"v":[[-32.206,-0.025],[-45.315,-10.446],[-41.768,-26.866],[-28.659,-16.445]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[4.453,-1.65],[2.557,7.383],[-4.453,1.65],[-2.557,-7.383]],"o":[[-4.455,1.651],[-2.557,-7.383],[4.455,-1.651],[2.557,7.383]],"v":[[-30.727,0.442],[-43.424,-9.938],[-39.988,-26.294],[-27.292,-15.913]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[3.859,-1.629],[2.216,7.291],[-3.859,1.629],[-2.216,-7.291]],"o":[[-3.86,1.63],[-2.216,-7.291],[3.86,-1.63],[2.216,7.291]],"v":[[-25.349,1.36],[-36.351,-8.891],[-33.374,-25.043],[-22.372,-14.792]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[2.285,-1.629],[1.312,7.291],[-2.285,1.629],[-1.312,-7.291]],"o":[[-2.286,1.63],[-1.312,-7.291],[2.286,-1.63],[1.312,7.291]],"v":[[-14.973,2.071],[-21.488,-8.18],[-19.725,-24.332],[-13.21,-14.081]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[1.119,-1.629],[0.643,7.291],[-1.119,1.629],[-0.643,-7.291]],"o":[[-1.12,1.63],[-0.643,-7.291],[1.12,-1.63],[0.643,7.291]],"v":[[-7.819,2.071],[-11.01,-8.18],[-10.147,-24.332],[-6.956,-14.081]],"c":true}]},{"t":85.833984375,"s":[{"i":[[0.357,-1.629],[0.205,7.291],[-0.357,1.629],[-0.205,-7.291]],"o":[[-0.357,1.63],[-0.205,-7.291],[0.357,-1.63],[0.205,7.291]],"v":[[-3.317,2.071],[-4.335,-8.18],[-4.06,-24.332],[-3.042,-14.081]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.678431391716,0.403921574354,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.996,145.54],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Head","np":4,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[32.75,0],[9.05,-8.723],[0,0],[0,0],[12.963,11.172]],"o":[[-36.75,0],[-9.05,8.723],[0,0],[0,0],[-12.963,-11.172]],"v":[[269.5,203.875],[202.375,231.25],[180.49,265.037],[357.49,265.037],[335.375,229.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[31.944,0],[8.827,-8.723],[0,0],[0,0],[12.644,11.172]],"o":[[-35.846,0],[-8.827,8.723],[0,0],[0,0],[-12.644,-11.172]],"v":[[269.549,203.875],[204.076,231.25],[186.694,262.646],[356.307,266.949],[333.803,229.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[29.964,0.368],[8.765,-9.559],[0,0],[0,0],[10.827,12.493]],"o":[[-28.262,-0.347],[-8.765,9.559],[0,0],[0,0],[-10.827,-12.493]],"v":[[266.904,204.072],[217.226,226.01],[201.569,257.67],[350.704,277.632],[328.366,234.753]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[17.745,0.368],[4.241,-8.325],[0,0],[0,0],[6.509,11.788]],"o":[[-16.737,-0.347],[-4.241,8.325],[0,0],[0,0],[-6.509,-11.788]],"v":[[266.953,203.361],[239.192,224.352],[231.398,251.757],[320.169,284.732],[304.709,236.885]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[8.691,0.368],[2.251,-8.436],[0,0],[0,0],[2.817,13.796]],"o":[[-8.197,-0.347],[-2.251,8.436],[0,0],[0,0],[-2.817,-13.796]],"v":[[268.056,203.598],[254.994,222.223],[251.276,250.581],[295.322,287.805],[287.494,239.724]],"c":true}]},{"t":85.833984375,"s":[{"i":[[2.773,0.368],[0.492,-8.596],[0,0],[0,0],[0.699,12.45]],"o":[[-2.615,-0.347],[-0.492,8.596],[0,0],[0,0],[-0.699,-12.45]],"v":[[269.236,203.598],[265.068,222.223],[263.435,250.823],[278.044,286.855],[275.437,239.724]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105865478516,0.450958251953,0.901947021484,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[403.855,266.954],[134.263,267.281],[133.746,34.114],[403.983,33.534]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[407.68,272.93],[141.435,262.261],[141.874,38.656],[408.046,28.992]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":72.5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[405.196,278.275],[150.215,255.604],[150.652,44.48],[407.113,22.696]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[395.085,285.526],[168.051,250.854],[169.441,49.35],[394.738,15.446]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[372.271,290.107],[194.58,245.643],[195.101,57.011],[373.426,8.258]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[351.971,291.685],[212.112,242.326],[211.844,59.063],[352.098,8.576]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[310.1,293.583],[241.912,240.199],[241.881,60.48],[309.976,6.207]],"c":true}]},{"t":85.833984375,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[279.372,300.675],[263.178,242.092],[263.608,59.062],[278.826,1.479]],"c":true}]}],"ix":2},"nm":"Mask","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.815673828125,0.88232421875,0.980377197266,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Background","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":87,"st":60,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"CAMERA_CASING 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[0,0],[0,13.689],[2.562,0.203],[0,0],[0.235,-13.941],[0,0],[-0.817,-3.47],[0,3.644],[0,21.647],[0,11.447]],"o":[[0,0],[0,-11.515],[-0.278,-0.022],[0,0],[-0.157,9.303],[0,0],[3.866,-2.97],[0,-3.644],[0,-5.657],[0,-17.18]],"v":[[355.812,-582.217],[355.812,-651.939],[349.438,-666.703],[349.561,-458.372],[349.68,-455.309],[349.716,-452.543],[349.634,-442.155],[355.812,-452.231],[355.812,-527.897],[355.812,-557.197]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84,"s":[{"i":[[0,0],[0.181,13.689],[3.692,-3.049],[0,0],[0.235,-13.941],[0,0],[-0.817,-3.47],[0.115,3.644],[0.08,21.647],[0.011,11.447]],"o":[[0,0],[-0.152,-11.515],[-0.215,0.151],[0,0],[-0.157,9.303],[0,0],[3.866,-2.97],[-0.115,-3.644],[-0.021,-5.657],[-0.017,-17.18]],"v":[[291.635,-587.821],[292.523,-742.756],[283.027,-757.519],[282.695,-373.749],[282.814,-370.686],[282.85,-362.418],[282.768,-352.029],[291.612,-362.105],[291.605,-533.5],[291.592,-562.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85,"s":[{"i":[[0,0],[0.355,13.689],[6.542,-0.922],[0,0],[0.37,-13.941],[0,0],[0.057,-3.845],[-0.362,3.644],[-0.253,21.647],[-0.035,11.447]],"o":[[0,0],[-0.298,-11.515],[-0.366,0.052],[0,0],[-0.247,9.303],[0,0],[5.807,-4.595],[0.362,-3.644],[0.066,-5.657],[0.053,-17.18]],"v":[[193.824,-593.342],[194.689,-728.224],[178.533,-742.988],[177.933,-357.043],[178.12,-353.042],[178.176,-343.402],[177.975,-332.388],[193.487,-347.215],[193.916,-523.397],[193.959,-552.697]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86,"s":[{"i":[[0,0],[0.484,13.689],[8.523,-3.859],[0,0],[0.505,-13.941],[0,0],[-1.753,-3.47],[-0.867,3.644],[-0.607,21.647],[-0.085,11.447]],"o":[[0,0],[-0.407,-11.515],[-0.429,0.194],[0,0],[-0.337,9.303],[0,0],[5.997,-7.47],[0.867,-3.644],[0.159,-5.657],[0.128,-17.18]],"v":[[75.679,-597.849],[75.758,-718.949],[53.719,-733.713],[53.693,-344.334],[53.947,-321.896],[54.024,-312.256],[53.705,-300.617],[75.218,-335.193],[75.9,-512.279],[76.004,-541.578]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87,"s":[{"i":[[0,0],[3.485,11.583],[8.955,-4.433],[-0.062,-3.091],[-3.221,-11.86],[0,0],[-2.544,-3.333],[-1.095,5.54],[-0.607,21.647],[3.44,10.582]],"o":[[0,0],[-3.366,-10.6],[-0.589,2.321],[0.062,3.09],[2.943,8.704],[0,0],[8.347,0.703],[0.794,-8.444],[0.159,-5.657],[-3.981,-16.052]],"v":[[0.007,-686.694],[-13.977,-729.743],[-42.282,-733.704],[-42.419,-351.824],[-35.506,-318.32],[-18.172,-282.143],[-17.207,-281.536],[4.303,-291.511],[7.882,-626.94],[5.009,-672.742]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88,"s":[{"i":[[0,0],[7.233,7.337],[10.246,-6.152],[-0.246,-12.344],[-9.136,-8.623],[0,0],[-4.913,-2.921],[-1.776,11.215],[-0.607,21.647],[9.871,10.62]],"o":[[0,0],[-7.601,-8.337],[-1.067,8.69],[0.246,12.344],[9.086,7.021],[0,0],[8.647,1.223],[0.576,-22.816],[0.159,-5.657],[-9.656,-13.055]],"v":[[-96.036,-712.675],[-118.855,-734.697],[-147.972,-735.599],[-146.863,-351.098],[-130.294,-314.045],[-110.979,-299.591],[-90.581,-288.487],[-69.43,-302.648],[-68.325,-642.738],[-74.855,-686.091]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0,0],[9.484,3.793],[8.601,-12.274],[-0.441,-20.809],[-28.549,-9.001],[0,0],[-12.63,-1.571],[-1.485,15.967],[0.068,21.914],[19.53,9.541]],"o":[[0,0],[-23.711,-9.556],[-2.126,56.648],[0.441,20.809],[21.714,6.2],[0,0],[16.655,-5.885],[0.585,-24.671],[-0.31,-11.754],[-24.908,-11.845]],"v":[[-256.274,-730.569],[-286.913,-744.674],[-328.463,-731.93],[-328.345,-350.477],[-292.838,-292.848],[-262.739,-284.553],[-227.494,-275.913],[-199.734,-301.739],[-198.453,-680.107],[-223.793,-715.645]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93,"s":[{"i":[[0,0],[10.869,1.69],[0.025,-8.377],[-0.642,-28.87],[-23.311,-3.439],[0,0],[-22.891,-2.452],[-0.707,20.252],[1.081,22.315],[30.895,7.44]],"o":[[0,0],[-26.095,-4.058],[-0.004,1.43],[0.642,28.87],[18.067,2.665],[0,0],[13.227,-9.056],[0.707,-20.252],[-1.012,-20.899],[-21.169,-6.833]],"v":[[-441.081,-726.063],[-476.791,-733.581],[-512.894,-713.271],[-514.67,-343.981],[-483.267,-295.903],[-442.821,-290.271],[-385.72,-282.768],[-366.552,-319.504],[-367.271,-675.98],[-402.702,-717.321]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95,"s":[{"i":[[0,0],[10.926,1.148],[0.925,-11.98],[-0.642,-28.87],[-25.802,-3.644],[0,0],[-22.916,-2.187],[-0.707,20.252],[1.081,22.315],[31.032,6.862]],"o":[[0,0],[-23.328,-2.596],[-0.085,1.425],[0.642,28.87],[22.11,3.111],[0,0],[17.386,-3.626],[0.707,-20.252],[-1.012,-20.899],[-22.091,-5.737]],"v":[[-499.893,-697.032],[-539.989,-704.551],[-576.438,-678.34],[-576.108,-326.385],[-541.208,-279.351],[-496.322,-272.988],[-445.018,-267.521],[-419.062,-304.309],[-419.608,-647.001],[-459.425,-688.969]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.293,-3.849],[0,0],[-22.941,-1.921],[-0.707,20.252],[1.081,22.315],[31.169,6.285]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[26.153,3.558],[0,0],[21.546,1.805],[0.707,-20.252],[-1.012,-20.899],[-23.012,-4.64]],"v":[[-551.186,-680.532],[-595.667,-688.051],[-632.464,-655.94],[-635.041,-321.32],[-596.641,-275.331],[-547.318,-268.237],[-501.809,-264.806],[-469.065,-301.646],[-464.426,-630.554],[-508.629,-673.148]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":99,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.293,-3.849],[0,0],[-22.942,-1.921],[-0.707,20.252],[1.081,22.315],[31.169,6.285]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[26.153,3.558],[0,0],[21.546,1.805],[0.707,-20.252],[-1.012,-20.899],[-23.012,-4.64]],"v":[[-580.634,-669.881],[-625.743,-675.52],[-662.539,-643.409],[-665.116,-312.548],[-626.717,-266.559],[-578.646,-260.091],[-531.884,-256.034],[-499.14,-292.875],[-493.875,-620.529],[-536.825,-663.123]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.293,-3.849],[0,0],[-22.941,-1.921],[-0.707,20.252],[1.081,22.315],[31.169,6.285]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[26.153,3.558],[0,0],[21.546,1.805],[0.707,-20.252],[-1.012,-20.899],[-23.012,-4.64]],"v":[[-607.577,-656.723],[-648.299,-660.483],[-685.096,-628.371],[-687.672,-308.789],[-649.273,-262.799],[-602.456,-256.958],[-554.441,-252.274],[-521.697,-289.115],[-523.323,-607.997],[-565.02,-650.592]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.293,-3.849],[0,0],[-21.06,0.551],[-0.707,20.252],[1.081,22.315],[29.62,2.879]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[26.153,3.558],[0,0],[21.614,-0.566],[0.707,-20.252],[-1.012,-20.899],[-23.365,-2.271]],"v":[[-621.361,-629.154],[-663.337,-631.66],[-700.133,-599.549],[-700.203,-298.764],[-661.804,-252.774],[-612.481,-248.187],[-565.719,-246.009],[-535.481,-286.609],[-538.361,-582.935],[-580.058,-625.529]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.293,-3.849],[0,0],[-21.06,0.551],[-0.707,20.252],[1.081,22.315],[29.62,2.879]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[26.153,3.558],[0,0],[21.614,-0.566],[0.707,-20.252],[-1.012,-20.899],[-23.365,-2.271]],"v":[[-620.108,-617.876],[-663.337,-619.129],[-700.133,-587.018],[-702.71,-292.498],[-664.311,-246.509],[-614.987,-244.427],[-570.731,-243.502],[-537.987,-280.343],[-535.855,-572.91],[-577.551,-615.504]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.457,-2.338],[0,0],[-21.06,0.551],[-0.707,20.252],[1.081,22.315],[29.62,2.879]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[28.045,2.304],[0,0],[21.614,-0.566],[0.707,-20.252],[-1.012,-20.899],[-23.365,-2.271]],"v":[[-620.108,-605.344],[-663.337,-605.345],[-700.133,-573.233],[-699.589,-281.22],[-661.19,-235.231],[-614.372,-231.896],[-570.117,-230.971],[-537.373,-267.812],[-542.12,-561.631],[-576.298,-602.973]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.524,-1.302],[0,0],[-21.06,0.551],[-0.707,20.252],[1.081,22.315],[29.62,2.879]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[23.032,1.051],[0,0],[21.614,-0.566],[0.707,-20.252],[-1.012,-20.899],[-23.365,-2.271]],"v":[[-615.095,-592.813],[-658.324,-592.813],[-695.121,-560.702],[-694.577,-276.207],[-656.177,-230.218],[-610.613,-229.39],[-568.864,-229.718],[-536.12,-266.559],[-535.855,-549.1],[-572.539,-591.695]],"c":true}]},{"t":126,"s":[{"i":[[0,0],[10.983,0.606],[1.825,-15.582],[-0.642,-28.87],[-28.524,-1.302],[0,0],[-21.06,0.551],[-0.707,20.252],[1.081,22.315],[29.62,2.879]],"o":[[0,0],[-20.561,-1.134],[-0.166,1.42],[0.642,28.87],[23.032,1.051],[0,0],[21.614,-0.566],[0.707,-20.252],[-1.012,-20.899],[-23.365,-2.271]],"v":[[-605.07,-581.535],[-648.299,-581.535],[-685.096,-549.424],[-685.805,-263.676],[-647.406,-217.687],[-601.841,-216.858],[-560.092,-217.187],[-527.348,-259.04],[-528.336,-541.582],[-562.514,-580.417]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294118524,0.250980407,0.262745112181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":84,"op":342,"st":60,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"FRONT_SCREEN 4","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0.25,-9.25],[0,0],[0.25,-0.5],[0,0],[0.5,9.25],[0,0],[-2,-2.5],[0,0]],"o":[[0,0],[0.25,3],[0,0],[-2,2.75],[0,0],[0,-16.016],[0,0],[1.75,3.5]],"v":[[-308,-465.5],[-308,477.25],[-308.25,483],[-356.25,568.25],[-364,573.75],[-364,-560.5],[-354.5,-565],[-310.5,-483]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88.334,"s":[{"i":[[1,-13],[0,0],[5,-5],[0,0],[0,16.016],[0,0],[-18,-17],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-11.25,9],[0,0],[0,-16.016],[0,0],[5.5,4.5]],"v":[[-257,-464],[-257,468],[-270.5,493.062],[-345.5,568.5],[-358.25,553.75],[-357,-542.5],[-338,-559],[-265.5,-485.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":89.166,"s":[{"i":[[0.667,-14.005],[0,0],[8.672,-3.333],[0,0],[0,16.016],[0,0],[-17.339,-11.333],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-12.839,6],[0,0],[0,-16.016],[0,0],[9.005,3]],"v":[[-210.667,-462.333],[-210.667,466],[-229.333,495.708],[-334.833,568.667],[-353,549.167],[-352.167,-541.5],[-329.833,-562.167],[-226,-489.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0.333,-15.011],[0,0],[12.344,-1.667],[0,0],[0,16.016],[0,0],[-16.677,-5.667],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-14.427,3],[0,0],[0,-16.016],[0,0],[12.511,1.5]],"v":[[-167.833,-460.667],[-167.833,464],[-191.667,498.354],[-324.167,568.833],[-347.75,544.583],[-347.333,-540.5],[-321.667,-565.333],[-190,-493.833]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-127,-459],[-127,462],[-156,501],[-313.5,569],[-342.5,540],[-342.5,-539.5],[-313.5,-568.5],[-156,-498]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-89.667,-464.667],[-89.667,467.333],[-118.667,503],[-308.667,571.333],[-337.667,542.333],[-337.667,-541.333],[-308.667,-570.333],[-118.667,-500.333]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":92.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-54.833,-470.333],[-54.833,472.667],[-83.833,505],[-303.833,573.667],[-332.833,544.667],[-332.833,-543.167],[-303.833,-572.167],[-83.833,-502.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-24,-476],[-24,478],[-53,507],[-299,576],[-328,547],[-328,-545],[-299,-574],[-53,-505]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":94.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[6.073,-479.4],[6.073,481.5],[-22.927,510.5],[-297.12,577.1],[-326.12,548.1],[-326.12,-546.2],[-297.12,-575.2],[-22.927,-508.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[32.647,-482.8],[32.647,485],[3.647,514],[-295.24,578.2],[-324.24,549.2],[-324.24,-547.4],[-295.24,-576.4],[3.647,-511.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[57.22,-486.2],[57.22,488.5],[28.22,517.5],[-293.36,579.3],[-322.36,550.3],[-322.36,-548.6],[-293.36,-577.6],[28.22,-515.2]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[79.46,-489.6],[79.46,492],[50.46,521],[-291.48,580.4],[-320.48,551.4],[-320.48,-549.8],[-291.48,-578.8],[50.46,-518.6]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[99.7,-493],[99.7,495.5],[70.7,524.5],[-289.6,581.5],[-318.6,552.5],[-318.6,-551],[-289.6,-580],[70.7,-522]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":99.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[136.58,-499.8],[136.58,502.5],[107.58,531.5],[-285.84,583.7],[-314.84,554.7],[-314.84,-553.4],[-285.84,-582.4],[107.58,-528.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[179.4,-510],[179.4,513],[150.4,542],[-280.2,587],[-309.2,558],[-309.2,-557],[-280.2,-586],[150.4,-539]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":103.334,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[201.28,-516],[201.28,518.8],[172.28,547.8],[-279.44,588.2],[-308.44,559.2],[-308.44,-558],[-279.44,-587],[172.28,-545]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[212.053,-519],[212.053,521.7],[183.053,550.7],[-279.06,588.8],[-308.06,559.8],[-308.06,-558.5],[-279.06,-587.5],[183.053,-548]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[220.827,-522],[220.827,524.6],[191.827,553.6],[-278.68,589.4],[-307.68,560.4],[-307.68,-559],[-278.68,-588],[191.827,-551]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[229.1,-525],[229.1,527.5],[200.1,556.5],[-278.3,590],[-307.3,561],[-307.3,-559.5],[-278.3,-588.5],[200.1,-554]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":109.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[256.46,-535.4],[256.46,537.5],[227.46,566.5],[-276.78,592.4],[-305.78,563.4],[-305.78,-561.5],[-276.78,-590.5],[227.46,-564.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":110,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[260.8,-538],[260.8,540],[231.8,569],[-276.4,593],[-305.4,564],[-305.4,-562],[-276.4,-591],[231.8,-567]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":112.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[273.82,-543.7],[273.82,546],[244.82,575],[-276.16,594.2],[-305.16,565.2],[-305.16,-562.6],[-276.16,-591.6],[244.82,-572.7]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":114.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[280.833,-547.5],[280.833,550],[251.833,579],[-276,595],[-305,566],[-305,-563],[-276,-592],[251.833,-576.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[294.867,-555],[294.867,558],[265.867,587],[-275.6,597],[-304.6,568],[-304.6,-564],[-275.6,-593],[265.867,-584]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":122.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[301.9,-559.5],[301.9,563],[272.9,592],[-275.7,597],[-304.7,568],[-304.7,-565],[-275.7,-594],[272.9,-588.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[306.933,-564],[306.933,568],[277.933,597],[-275.8,597],[-304.8,568],[-304.8,-566],[-275.8,-595],[277.933,-593]],"c":true}]},{"t":135,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[310,-568],[310,570],[281,599],[-276,599],[-305,570],[-305,-568],[-276,-597],[281,-597]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.815686285496,0.882352948189,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[384,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[102,102],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":88,"op":342,"st":60,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Figure 7","tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":93.334,"s":[0]},{"t":101.666015625,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[207.459,144.79,0],"to":[0.312,0,0],"ti":[-1.146,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.779,"s":[209.334,144.79,0],"to":[1.146,0,0],"ti":[-2.125,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.555,"s":[214.334,144.79,0],"to":[2.125,0,0],"ti":[-2.812,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[222.084,144.79,0],"to":[2.812,0,0],"ti":[-4.396,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":71.111,"s":[231.209,144.79,0],"to":[4.396,0,0],"ti":[-5.104,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[248.459,144.79,0],"to":[5.104,0,0],"ti":[-3.812,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.223,"s":[261.834,144.79,0],"to":[3.812,0,0],"ti":[-2.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.779,"s":[271.334,144.79,0],"to":[2.667,0,0],"ti":[-1.812,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[277.834,144.79,0],"to":[1.812,0,0],"ti":[-1.083,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":98.889,"s":[282.209,144.79,0],"to":[1.083,0,0],"ti":[-0.458,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.445,"s":[284.334,144.79,0],"to":[0.458,0,0],"ti":[-0.104,0,0]},{"t":110,"s":[284.959,144.79,0]}],"ix":2,"l":2},"a":{"a":0,"k":[270.209,145.54,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.55,0.55,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.001]},"t":60,"s":[108,108,100]},{"t":110,"s":[106.5,106.5,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0,0],[-0.095,-1.387],[0.299,-1.3],[0.045,1.308]],"o":[[0.052,0.711],[0.119,1.734],[-0.239,1.04],[0,0]],"v":[[-57.799,-6.034],[-57.522,-2.167],[-57.671,6.182],[-58.104,3.557]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0,0],[-0.232,-1.387],[0.725,-1.3],[0.109,1.308]],"o":[[0.127,0.711],[0.29,1.734],[-0.58,1.04],[0,0]],"v":[[-53.069,-6.034],[-52.397,-2.167],[-52.759,6.182],[-53.809,3.557]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0,0],[-0.59,-1.387],[1.846,-1.3],[0.276,1.308]],"o":[[0.325,0.711],[0.738,1.734],[-1.477,1.04],[0,0]],"v":[[-41.097,-6.034],[-39.386,-2.167],[-40.307,6.182],[-42.981,3.557]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0,0],[-0.953,-1.387],[2.979,-1.3],[0.446,1.308]],"o":[[0.524,0.711],[1.191,1.734],[-2.384,1.04],[0,0]],"v":[[-29.746,-6.034],[-26.986,-2.167],[-28.473,6.182],[-32.788,3.557]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0,0],[-1.277,-1.387],[3.993,-1.3],[0.598,1.308]],"o":[[0.702,0.711],[1.596,1.734],[-3.195,1.04],[0,0]],"v":[[-19.728,-6.034],[-16.028,-2.167],[-18.021,6.182],[-23.805,3.557]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[0,0],[-1.471,-1.387],[4.599,-1.3],[0.688,1.308]],"o":[[0.809,0.711],[1.838,1.734],[-3.68,1.04],[0,0]],"v":[[-13.958,-6.034],[-9.695,-2.167],[-11.991,6.182],[-18.654,3.557]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[0,0],[-1.612,-1.387],[5.042,-1.3],[0.754,1.308]],"o":[[0.886,0.711],[2.015,1.734],[-4.034,1.04],[0,0]],"v":[[-9.542,-6.034],[-4.87,-2.167],[-7.386,6.182],[-14.689,3.557]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[0,0],[-1.826,-1.387],[5.71,-1.3],[0.854,1.308]],"o":[[1.004,0.711],[2.282,1.734],[-4.569,1.04],[0,0]],"v":[[-8.492,-6.268],[-3.201,-2.402],[-6.051,5.947],[-14.321,3.322]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[0,0],[-1.802,-1.387],[5.635,-1.3],[0.843,1.308]],"o":[[0.991,0.711],[2.252,1.734],[-4.509,1.04],[0,0]],"v":[[-5.336,-6.268],[-0.114,-2.402],[-2.926,5.947],[-11.089,3.322]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[0,0],[-1.899,-1.387],[5.939,-1.3],[0.889,1.308]],"o":[[1.044,0.711],[2.374,1.734],[-4.752,1.04],[0,0]],"v":[[-2.334,-6.268],[3.169,-2.402],[0.205,5.947],[-8.397,3.322]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[0,0],[-1.939,-1.387],[6.061,-1.3],[0.907,1.308]],"o":[[1.066,0.711],[2.423,1.734],[-4.85,1.04],[0,0]],"v":[[-0.934,-6.268],[4.683,-2.402],[1.658,5.947],[-7.122,3.322]],"c":false}]},{"t":135,"s":[{"i":[[0,0],[-1.939,-1.387],[6.061,-1.3],[0.907,1.308]],"o":[[1.066,0.711],[2.423,1.734],[-4.85,1.04],[0,0]],"v":[[-0.582,-6.237],[5.035,-2.37],[2.01,5.979],[-6.77,3.354]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.596078455448,0.321568638086,0.239215686917,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.12,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[272.026,152.086],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[-0.193,7.277],[-0.436,0],[-0.204,3.66],[0.902,-0.059],[0.071,-14.068],[-0.242,0]],"o":[[0.15,8.062],[0.245,0],[-0.171,-14.63],[-0.9,0.059],[0.185,2.604],[0.436,0]],"v":[[-56.249,5.695],[-55.215,18.856],[-54.713,13.904],[-56.412,-10.293],[-57.945,12.606],[-57.189,17.449]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[-0.47,7.277],[-1.059,0],[-0.496,3.66],[2.191,-0.059],[0.174,-14.068],[-0.588,0]],"o":[[0.364,8.062],[0.596,0],[-0.415,-14.63],[-2.185,0.059],[0.449,2.604],[1.059,0]],"v":[[-51.53,5.695],[-49.016,18.856],[-47.797,13.904],[-51.926,-10.293],[-55.649,12.606],[-53.813,17.449]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[-1.196,7.277],[-2.695,0],[-1.262,3.66],[5.577,-0.059],[0.442,-14.068],[-1.497,0]],"o":[[0.928,8.062],[1.517,0],[-1.057,-14.63],[-5.564,0.059],[1.144,2.604],[2.695,0]],"v":[[-39.584,5.695],[-33.184,18.856],[-30.08,13.904],[-40.592,-10.293],[-50.072,12.606],[-45.396,17.449]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[-1.93,7.277],[-4.349,0],[-1.859,2.669],[8.999,-0.059],[0.713,-14.068],[-2.416,0]],"o":[[1.497,8.062],[2.449,0],[-1.705,-14.63],[-8.978,0.059],[1.845,2.604],[4.349,0]],"v":[[-28.26,5.461],[-18.311,18.388],[-12.925,13.904],[-29.887,-10.293],[-45.183,12.606],[-38.394,17.215]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[-2.586,7.277],[-5.829,0],[-2.492,2.669],[12.062,-0.059],[0.956,-14.068],[-3.238,0]],"o":[[2.007,8.062],[3.282,0],[-0.557,-15.213],[-12.034,0.059],[2.474,2.604],[5.829,0]],"v":[[-18.266,5.461],[-4.931,18.388],[2.289,13.904],[-20.446,-11.464],[-40.949,12.606],[-31.849,17.215]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[-2.979,7.277],[-6.715,0],[-2.871,2.669],[13.894,-0.059],[0.615,-15.17],[-3.73,0]],"o":[[2.311,8.062],[3.781,0],[-0.642,-15.213],[-13.862,0.059],[2.849,2.604],[6.715,0]],"v":[[-12.51,4.992],[2.851,17.685],[11.168,13.904],[-15.292,-12.168],[-38.639,12.606],[-28.157,16.746]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[-3.266,7.277],[-7.36,0],[-3.147,2.669],[15.23,-0.059],[0.674,-15.17],[-4.089,0]],"o":[[2.534,8.062],[4.144,0],[-0.703,-15.213],[-15.194,0.059],[3.123,2.604],[7.36,0]],"v":[[-8.876,4.523],[7.962,17.215],[17.592,12.496],[-10.382,-13.106],[-37.517,11.903],[-26.284,16.511]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[-3.478,7.277],[-7.839,0],[-3.352,2.669],[16.221,-0.059],[0.718,-15.17],[-4.355,0]],"o":[[3.478,7.277],[4.414,0],[-0.749,-15.213],[-16.184,0.059],[3.327,2.604],[7.839,0]],"v":[[-5.981,4.288],[11.703,16.746],[21.96,12.496],[-7.336,-13.576],[-36.487,11.903],[-24.772,16.511]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[-3.65,7.277],[-8.226,0],[-3.517,2.669],[17.022,-0.059],[0.753,-15.17],[-4.57,0]],"o":[[3.65,7.277],[4.632,0],[-0.786,-15.213],[-16.983,0.059],[3.491,2.604],[8.226,0]],"v":[[-3.376,3.819],[15.182,16.511],[26.438,12.496],[-4.797,-14.514],[-35.635,11.668],[-23.342,16.511]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[-3.847,7.277],[-8.67,0],[-3.707,2.669],[17.939,-0.059],[0.794,-15.17],[-4.816,0]],"o":[[3.847,7.277],[4.881,0],[-0.828,-15.213],[-17.898,0.059],[3.679,2.604],[8.67,0]],"v":[[-1.836,3.584],[18.215,15.807],[31.315,11.557],[-1.85,-15.923],[-34.843,11.668],[-21.888,15.807]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[-3.926,7.277],[-8.848,0],[-3.783,2.669],[18.309,-0.059],[0.81,-15.17],[-4.916,0]],"o":[[3.926,7.277],[4.982,0],[-0.845,-15.213],[-18.267,0.059],[3.755,2.604],[8.848,0]],"v":[[-0.458,3.584],[20.007,15.807],[33.377,11.557],[-0.472,-15.923],[-34.145,11.668],[-20.923,15.807]],"c":true}]},{"t":135,"s":[{"i":[[-3.926,7.277],[-8.848,0],[-3.783,2.669],[18.309,-0.059],[0.81,-15.17],[-4.916,0]],"o":[[3.926,7.277],[4.982,0],[-0.845,-15.213],[-18.267,0.059],[3.755,2.604],[8.848,0]],"v":[[-0.106,3.616],[20.359,15.839],[33.729,11.589],[-0.12,-15.891],[-33.793,11.7],[-20.571,15.839]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0,9.283],[0.481,0],[0,-9.283],[-0.481,0]],"o":[[0,-9.283],[-0.481,0],[0,9.283],[0.481,0]],"v":[[-56.552,-17.322],[-57.474,-33.907],[-58.358,-17.994],[-57.435,-0.961]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0,9.283],[1.168,0],[0,-9.283],[-1.168,0]],"o":[[0,-9.283],[-1.168,0],[0,9.283],[1.168,0]],"v":[[-52.264,-17.322],[-54.505,-33.907],[-56.652,-17.994],[-54.41,-0.961]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0,9.283],[2.973,0],[0,-9.283],[-2.973,0]],"o":[[0,-9.283],[-2.973,0],[0,9.283],[2.973,0]],"v":[[-41.453,-17.322],[-47.159,-33.907],[-52.623,-17.994],[-46.917,-0.961]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0,9.283],[4.797,0],[0,-9.283],[-4.797,0]],"o":[[0,-9.283],[-4.797,0],[0,9.283],[4.797,0]],"v":[[-31.654,-18.258],[-40.861,-34.843],[-49.678,-18.931],[-40.471,-1.898]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0,9.532],[6.43,0],[0,-9.532],[-6.43,0]],"o":[[0,-9.532],[-6.43,0],[0,9.532],[6.43,0]],"v":[[-22.815,-18.985],[-35.156,-36.015],[-46.974,-19.676],[-34.633,-2.186]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[0,9.532],[7.407,0],[0,-9.532],[-7.407,0]],"o":[[0,-9.532],[-7.407,0],[0,9.532],[7.407,0]],"v":[[-18.02,-19.689],[-32.236,-36.718],[-45.85,-20.379],[-31.633,-2.89]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[0,9.723],[8.119,0],[0,-9.723],[-8.119,0]],"o":[[0,-9.723],[-8.119,0],[0,9.723],[8.119,0]],"v":[[-14.659,-20.051],[-30.241,-37.422],[-45.163,-20.755],[-29.58,-2.915]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[0,9.723],[8.648,0],[0,-9.723],[-8.648,0]],"o":[[0,-9.723],[-8.648,0],[0,9.723],[8.648,0]],"v":[[-11.89,-20.755],[-28.488,-38.126],[-44.381,-21.459],[-27.784,-3.619]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[0,9.723],[9.075,0],[0,-9.723],[-9.075,0]],"o":[[0,-9.723],[-9.075,0],[0,9.723],[9.075,0]],"v":[[-10.316,-21.459],[-26.748,-39.065],[-43.18,-21.459],[-26.748,-3.854]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[0,9.805],[9.607,0],[0,-9.805],[-9.607,0]],"o":[[0,-9.805],[-9.607,0],[0,9.805],[9.607,0]],"v":[[-8.19,-22.558],[-25.585,-40.312],[-42.981,-22.558],[-25.585,-4.804]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[0,9.805],[9.805,0],[0,-9.805],[-9.805,0]],"o":[[0,-9.805],[-9.805,0],[0,9.805],[9.805,0]],"v":[[-6.942,-22.558],[-24.697,-40.312],[-42.451,-22.558],[-24.697,-4.804]],"c":true}]},{"t":135,"s":[{"i":[[0,9.805],[9.805,0],[0,-9.805],[-9.805,0]],"o":[[0,-9.805],[-9.805,0],[0,9.805],[9.805,0]],"v":[[-6.59,-22.526],[-24.345,-40.281],[-42.099,-22.526],[-24.345,-4.772]],"c":true}]}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337254911661,0.23137255013,0.129411771894,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.47,108.276],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hair","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[-0.312,13.512],[0,0],[0,0],[-0.015,2.62],[0.001,4.351],[0,0],[-0.927,0.06],[-0.139,-15.255],[0,0],[-0.024,-2.669],[-0.092,-4.353],[-0.044,-3.988],[0,-4.307],[0.295,-3.002],[0.482,-0.349],[0.391,4.905],[0,7.994],[0,0]],"o":[[0,0],[0,0],[0.06,-4.479],[0.015,-2.598],[0,0],[-0.003,-15.806],[0.927,-0.06],[0,0],[0.001,4.276],[0.024,2.702],[0.178,8.387],[0.044,3.962],[0,7.459],[-0.49,4.981],[-0.608,0.441],[-0.407,-5.108],[0,0],[0,-6.072]],"v":[[-58.689,-3.691],[-58.726,-4.5],[-58.724,-4.616],[-58.676,-14.567],[-58.471,-23.153],[-58.471,-23.222],[-56.937,-47.531],[-55.247,-22.97],[-55.247,-22.876],[-55.237,-14.204],[-55.068,-5.188],[-54.763,11.754],[-54.743,22.514],[-55.47,41.151],[-56.849,48.639],[-58.387,41.742],[-59.021,24.251],[-59.021,24.218]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[-0.757,13.512],[0,0],[0,0],[-0.037,2.62],[0.002,4.351],[0,0],[-2.253,0.06],[-0.337,-15.255],[0,0],[-0.058,-2.669],[-0.224,-4.353],[-0.106,-3.988],[0,-4.307],[0.717,-3.002],[1.17,-0.349],[0.95,4.905],[0,7.994],[0,0]],"o":[[0,0],[0,0],[0.146,-4.479],[0.037,-2.598],[0,0],[-0.006,-15.806],[2.253,-0.06],[0,0],[0.001,4.276],[0.059,2.702],[0.431,8.387],[0.106,3.962],[0,7.459],[-1.19,4.981],[-1.476,0.441],[-0.989,-5.108],[0,0],[0,-6.072]],"v":[[-56.705,-3.691],[-56.793,-4.5],[-56.789,-4.616],[-56.672,-14.567],[-56.176,-23.153],[-56.176,-23.222],[-52.448,-47.531],[-48.344,-22.97],[-48.344,-22.876],[-48.32,-14.204],[-47.909,-5.188],[-47.168,11.754],[-47.118,22.514],[-48.884,41.151],[-52.234,48.639],[-55.971,41.742],[-57.511,24.251],[-57.511,24.218]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[-1.928,13.512],[0,0],[0,0],[-0.095,2.62],[0.005,4.351],[0,0],[-5.736,0.06],[-0.858,-15.255],[0,0],[-0.149,-2.669],[-0.57,-4.353],[-0.271,-3.988],[0,-4.307],[1.826,-3.002],[2.98,-0.349],[2.418,4.905],[0,7.994],[0,0]],"o":[[0,0],[0,0],[0.372,-4.479],[0.094,-2.598],[0,0],[-0.015,-15.806],[5.736,-0.06],[0,0],[0.004,4.276],[0.151,2.702],[1.098,8.387],[0.269,3.962],[0,7.459],[-3.03,4.981],[-3.758,0.441],[-2.518,-5.108],[0,0],[0,-6.072]],"v":[[-51.946,-3.691],[-52.17,-4.5],[-52.161,-4.616],[-51.862,-14.567],[-50.599,-23.153],[-50.599,-23.222],[-41.108,-47.531],[-30.66,-22.97],[-30.66,-22.876],[-30.598,-14.204],[-29.552,-5.188],[-27.667,11.754],[-27.539,22.514],[-32.036,41.151],[-40.564,48.639],[-50.078,41.742],[-53.999,24.251],[-53.999,24.218]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[-3.112,13.512],[0,0],[0,0],[-0.153,2.62],[0.007,4.351],[0,0],[-9.255,0.06],[-1.384,-15.255],[0,0],[-0.24,-2.669],[-0.919,-4.353],[-0.437,-3.988],[0,-4.307],[2.946,-3.002],[4.808,-0.349],[3.902,4.905],[0,7.994],[0,0]],"o":[[0,0],[0,0],[0.601,-4.479],[0.152,-2.598],[0,0],[-0.025,-15.806],[9.255,-0.06],[0,0],[0.006,4.276],[0.243,2.702],[1.772,8.387],[0.434,3.962],[0,7.459],[-4.889,4.981],[-6.063,0.441],[-4.063,-5.108],[0,0],[0,-6.072]],"v":[[-47.884,-3.691],[-48.247,-4.5],[-48.231,-4.616],[-47.749,-14.567],[-45.712,-23.153],[-45.712,-23.222],[-30.397,-47.531],[-13.538,-22.97],[-13.538,-22.876],[-13.439,-14.204],[-11.75,-5.188],[-8.709,11.754],[-8.502,22.514],[-15.759,41.151],[-29.518,48.639],[-44.87,41.742],[-51.198,24.251],[-51.198,24.218]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[-4.171,13.512],[0,0],[0,0],[-0.205,2.62],[0.01,4.351],[0,0],[-12.405,0.06],[-0.034,-15.806],[0,0],[-0.322,-2.669],[-1.232,-4.353],[-0.586,-3.988],[0,-4.307],[5.048,-4.141],[6.445,-0.349],[5.23,4.905],[0,7.994],[0,0]],"o":[[0,0],[0,0],[0.805,-4.479],[0.203,-2.598],[0,0],[-0.033,-15.806],[12.405,-0.06],[0,0],[0.008,4.276],[0.326,2.702],[2.374,8.387],[0.582,3.962],[0,7.459],[-6.294,5.164],[-8.127,0.441],[-5.446,-5.108],[0,0],[0,-6.072]],"v":[[-44.39,-3.691],[-44.876,-4.5],[-44.856,-4.616],[-44.21,-14.567],[-41.478,-23.153],[-41.478,-23.222],[-20.951,-48.702],[1.646,-22.97],[1.646,-22.876],[1.78,-14.204],[4.043,-5.188],[8.119,11.754],[8.71,22.982],[-1.017,41.619],[-19.46,49.108],[-40.037,42.211],[-48.832,24.251],[-48.832,24.218]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[-4.804,13.512],[0,0],[0,0],[-0.236,2.62],[0.011,4.351],[0,0],[-14.289,0.06],[-0.039,-15.806],[0,0],[-0.371,-2.669],[-1.42,-4.353],[-0.675,-3.988],[0,-4.307],[6.374,-5.095],[7.424,-0.349],[6.025,4.905],[0,7.994],[0,0]],"o":[[0,0],[0,0],[0.927,-4.479],[0.234,-2.598],[0,0],[-0.038,-15.806],[14.289,-0.06],[0,0],[0.01,4.276],[0.375,2.702],[2.735,8.387],[0.671,3.962],[0,7.459],[-6.899,5.515],[-9.362,0.441],[-6.274,-5.108],[0,0],[0,-6.072]],"v":[[-42.523,-3.691],[-43.083,-4.5],[-43.059,-4.616],[-42.315,-14.567],[-39.169,-23.153],[-39.169,-23.222],[-15.793,-49.406],[10.507,-22.97],[10.507,-22.876],[10.661,-14.204],[13.268,-5.188],[17.964,11.754],[18.644,22.982],[7.44,42.557],[-13.805,50.046],[-37.508,43.149],[-47.64,24.251],[-47.64,24.218]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[-5.266,13.512],[0,0],[0,0],[-0.259,2.62],[0.012,4.351],[0,0],[-15.663,0.06],[-0.042,-15.806],[0,0],[-0.407,-2.669],[-1.556,-4.353],[-0.74,-3.988],[0,-4.307],[6.987,-5.095],[10.261,-0.04],[6.684,5.31],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.016,-4.479],[0.257,-2.598],[0,0],[-0.042,-15.806],[15.663,-0.06],[0,0],[0.011,4.276],[0.411,2.702],[2.998,8.387],[0.735,3.962],[0,7.459],[-7.562,5.515],[-10.273,0.04],[-6.687,-5.313],[0,0],[0,-6.072]],"v":[[-41.467,-3.925],[-42.08,-4.735],[-42.054,-4.851],[-40.724,-14.567],[-38.047,-23.857],[-38.047,-23.925],[-10.882,-50.344],[16.919,-24.377],[16.919,-24.283],[17.344,-14.204],[19.173,-5.188],[24.835,11.754],[25.58,22.982],[14.071,42.792],[-10.245,50.515],[-36.741,43.149],[-46.56,24.251],[-46.56,24.218]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[-5.609,13.512],[0,0],[0,0],[-0.276,2.62],[0.013,4.351],[0,0],[-16.682,0.06],[-0.045,-15.806],[0,0],[-0.433,-2.669],[-1.658,-4.353],[-0.788,-3.988],[0,-4.307],[7.101,-5.507],[10.929,-0.04],[7.119,5.31],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.083,-4.479],[0.273,-2.598],[0,0],[-0.045,-15.806],[16.682,-0.06],[0,0],[0.011,4.276],[0.438,2.702],[3.193,8.387],[0.783,3.962],[0,7.459],[-7.085,5.495],[-10.942,0.04],[-7.123,-5.313],[0,0],[0,-6.072]],"v":[[-40.159,-3.925],[-40.813,-4.735],[-40.785,-4.851],[-38.869,-14.567],[-37.017,-23.857],[-37.017,-23.925],[-7.833,-50.813],[21.277,-24.377],[21.277,-24.283],[21.73,-14.673],[24.928,-5.188],[30.958,11.754],[31.752,22.982],[19.493,43.261],[-7.655,50.984],[-35.376,43.384],[-46.085,24.486],[-46.085,24.453]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[-5.886,13.512],[0,0],[0,0],[-0.289,2.62],[0.014,4.351],[0,0],[-17.506,0.06],[-0.047,-15.806],[0,0],[-0.454,-2.669],[-1.739,-4.353],[-0.827,-3.988],[0,-4.307],[7.452,-5.507],[11.468,-0.04],[7.47,5.31],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.136,-4.479],[0.287,-2.598],[0,0],[-0.047,-15.806],[17.506,-0.06],[0,0],[0.012,4.276],[0.46,2.702],[3.351,8.387],[0.822,3.962],[0,7.459],[-7.435,5.495],[-11.482,0.04],[-7.475,-5.313],[0,0],[0,-6.072]],"v":[[-39.463,-4.63],[-39.41,-4.735],[-39.38,-4.851],[-37.37,-14.567],[-36.165,-24.092],[-36.165,-24.16],[-5.294,-51.752],[25.747,-24.377],[25.747,-24.283],[26.223,-14.673],[29.332,-4.954],[35.168,12.458],[36.001,23.687],[24.122,43.965],[-5.107,51.923],[-34.197,43.853],[-45.681,24.016],[-45.681,23.984]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[-7.295,13.962],[0,0],[0,0],[-0.305,2.62],[0.015,4.351],[0,0],[-18.449,0.06],[-0.05,-15.806],[0,0],[-0.479,-2.669],[-1.833,-4.353],[-0.871,-3.988],[0,-4.307],[7.853,-5.507],[12.086,-0.04],[7.873,5.31],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.197,-4.479],[0.302,-2.598],[0,0],[-0.05,-15.806],[18.449,-0.06],[0,0],[0.012,4.276],[0.485,2.702],[3.532,8.387],[0.866,3.962],[0,7.459],[-7.836,5.495],[-12.101,0.04],[-7.877,-5.313],[0,0],[0,-6.072]],"v":[[-37.86,-4.63],[-37.804,-4.735],[-37.773,-4.851],[-35.654,-14.567],[-35.374,-24.092],[-35.374,-24.16],[-2.345,-53.161],[30.863,-24.377],[30.863,-24.283],[31.364,-14.673],[34.641,-4.954],[40.79,12.458],[41.669,23.687],[29.15,43.965],[-1.653,53.097],[-32.557,44.557],[-45.155,23.978],[-45.155,23.945]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[-7.446,13.962],[0,0],[0,0],[-0.313,2.62],[0.015,4.351],[0,0],[-18.83,0.06],[-0.051,-15.806],[0,0],[-0.49,-2.669],[-1.873,-4.352],[-0.89,-3.988],[0,-4.307],[8.014,-5.508],[12.335,-0.04],[8.035,5.309],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.222,-4.479],[0.309,-2.598],[0,0],[-0.051,-15.806],[18.83,-0.06],[0,0],[0.013,4.276],[0.495,2.702],[3.604,8.387],[0.884,3.962],[0,7.459],[-7.997,5.495],[-12.35,0.04],[-8.04,-5.313],[0,0],[0,-6.072]],"v":[[-37.213,-4.63],[-37.156,-4.735],[-37.125,-4.851],[-34.962,-14.567],[-34.676,-24.092],[-34.676,-24.16],[-0.966,-53.161],[32.926,-24.377],[32.926,-24.283],[33.437,-14.673],[36.782,-4.954],[43.058,12.458],[43.955,23.687],[31.177,43.965],[-0.26,53.097],[-31.801,44.557],[-44.659,23.978],[-44.659,23.945]],"c":true}]},{"t":135,"s":[{"i":[[-7.446,13.962],[0,0],[0,0],[-0.313,2.62],[0.015,4.351],[0,0],[-18.83,0.06],[-0.051,-15.806],[0,0],[-0.49,-2.669],[-1.873,-4.352],[-0.89,-3.988],[0,-4.307],[8.014,-5.508],[12.335,-0.04],[8.035,5.309],[0,7.994],[0,0]],"o":[[0,0],[0,0],[1.222,-4.479],[0.309,-2.598],[0,0],[-0.051,-15.806],[18.83,-0.06],[0,0],[0.013,4.276],[0.495,2.702],[3.604,8.387],[0.884,3.962],[0,7.459],[-7.997,5.495],[-12.35,0.04],[-8.04,-5.313],[0,0],[0,-6.072]],"v":[[-36.861,-4.598],[-36.804,-4.703],[-36.772,-4.819],[-34.61,-14.535],[-34.324,-24.06],[-34.324,-24.128],[-0.614,-53.129],[33.278,-24.345],[33.278,-24.252],[33.789,-14.641],[37.134,-4.922],[43.41,12.489],[44.307,23.718],[31.53,43.997],[0.092,53.129],[-31.449,44.589],[-44.307,24.009],[-44.307,23.977]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0.226,1.656],[-0.13,7.412],[-0.226,-1.656],[0.13,-7.412]],"o":[[-0.227,-1.657],[0.13,-7.412],[0.227,1.657],[-0.13,7.412]],"v":[[-55.466,2.927],[-55.616,-13.258],[-54.921,-22.506],[-54.796,-6.555]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0.55,1.656],[-0.316,7.412],[-0.55,-1.656],[0.316,-7.412]],"o":[[-0.55,-1.657],[0.316,-7.412],[0.55,1.657],[-0.316,7.412]],"v":[[-48.875,2.927],[-49.239,-13.258],[-47.55,-22.506],[-47.247,-6.555]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[1.401,1.656],[-0.804,7.412],[-1.401,-1.656],[0.804,-7.412]],"o":[[-1.401,-1.657],[0.804,-7.412],[1.401,1.657],[-0.804,7.412]],"v":[[-32.013,2.927],[-32.939,-13.258],[-28.639,-22.506],[-27.867,-6.555]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[2.26,1.656],[-1.298,7.412],[-2.26,-1.656],[1.298,-7.412]],"o":[[-2.261,-1.657],[1.298,-7.412],[2.261,1.657],[-1.298,7.412]],"v":[[-15.721,2.927],[-17.217,-13.258],[-10.278,-22.506],[-9.031,-6.555]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[3.029,1.656],[-1.74,7.412],[-3.029,-1.656],[1.739,-7.412]],"o":[[-3.031,-1.657],[1.74,-7.412],[3.03,1.657],[-1.739,7.412]],"v":[[-0.652,2.224],[-2.656,-13.961],[6.643,-23.209],[8.315,-7.258]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[3.489,1.656],[-2.004,7.412],[-3.489,-1.656],[2.004,-7.412]],"o":[[-3.491,-1.657],[2.004,-7.412],[3.491,1.657],[-2.004,7.412]],"v":[[7.86,1.52],[5.551,-14.665],[16.264,-23.912],[18.189,-7.962]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[3.825,1.656],[-2.196,7.412],[-3.825,-1.656],[2.196,-7.412]],"o":[[-3.826,-1.657],[2.196,-7.412],[3.826,1.657],[-2.196,7.412]],"v":[[14.017,1.051],[11.486,-15.134],[23.228,-24.381],[25.339,-8.431]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[4.074,1.656],[-2.339,7.412],[-4.074,-1.656],[2.339,-7.412]],"o":[[-4.076,-1.657],[2.339,-7.412],[4.076,1.657],[-2.339,7.412]],"v":[[18.936,-0.122],[16.24,-16.307],[28.747,-25.555],[30.995,-9.604]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[4.275,1.656],[-2.455,7.412],[-4.275,-1.656],[2.455,-7.412]],"o":[[-4.277,-1.657],[2.455,-7.412],[4.277,1.657],[-2.455,7.412]],"v":[[23.29,-0.122],[20.462,-16.307],[33.587,-25.555],[35.946,-9.604]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[4.505,1.656],[-2.587,7.412],[-4.505,-1.656],[2.587,-7.412]],"o":[[-4.507,-1.657],[2.587,-7.412],[4.507,1.657],[-2.587,7.412]],"v":[[28.274,-0.122],[24.798,-16.542],[37.64,-26.963],[41.116,-10.543]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[4.598,1.656],[-2.64,7.412],[-4.598,-1.656],[2.64,-7.412]],"o":[[-4.6,-1.657],[2.64,-7.412],[4.6,1.657],[-2.64,7.412]],"v":[[30.283,-0.122],[26.736,-16.542],[39.843,-26.963],[43.39,-10.543]],"c":true}]},{"t":135,"s":[{"i":[[4.598,1.656],[-2.64,7.412],[-4.598,-1.656],[2.64,-7.412]],"o":[[-4.6,-1.657],[2.64,-7.412],[4.6,1.657],[-2.64,7.412]],"v":[[30.635,-0.09],[27.088,-16.51],[40.195,-26.931],[43.742,-10.511]],"c":true}]}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0.226,-1.656],[0.13,7.412],[-0.226,1.656],[-0.13,-7.412]],"o":[[-0.227,1.657],[-0.13,-7.412],[0.227,-1.657],[0.13,7.412]],"v":[[-58.448,-0.292],[-59.074,-9.887],[-58.879,-25.49],[-58.273,-15.539]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0.55,-1.656],[0.316,7.412],[-0.55,1.656],[-0.316,-7.412]],"o":[[-0.55,1.657],[-0.316,-7.412],[0.55,-1.657],[0.316,7.412]],"v":[[-56.118,-0.292],[-57.64,-9.887],[-57.165,-25.49],[-55.694,-15.539]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[1.401,-1.656],[0.804,7.412],[-1.401,1.656],[-0.804,-7.412]],"o":[[-1.401,1.657],[-0.804,-7.412],[1.401,-1.657],[0.804,7.412]],"v":[[-50.453,-0.292],[-54.326,-9.887],[-53.117,-25.49],[-49.372,-15.539]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[2.26,-1.656],[1.298,7.412],[-2.26,1.656],[-1.298,-7.412]],"o":[[-2.261,1.657],[-1.298,-7.412],[2.261,-1.657],[1.298,7.412]],"v":[[-45.475,-0.292],[-51.726,-9.887],[-49.775,-25.49],[-43.732,-15.539]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[3.029,-1.656],[1.739,7.412],[-3.029,1.656],[-1.739,-7.412]],"o":[[-3.03,1.657],[-1.739,-7.412],[3.03,-1.657],[1.739,7.412]],"v":[[-41.476,-0.761],[-49.854,-10.355],[-47.238,-25.959],[-39.139,-16.007]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[3.489,-1.656],[2.004,7.412],[-3.489,1.656],[-2.004,-7.412]],"o":[[-3.491,1.657],[-2.004,-7.412],[3.491,-1.657],[2.004,7.412]],"v":[[-39.166,-0.761],[-48.816,-10.355],[-45.804,-25.959],[-36.474,-16.007]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[3.825,-1.656],[2.196,7.412],[-3.825,1.656],[-2.196,-7.412]],"o":[[-3.826,1.657],[-2.196,-7.412],[3.826,-1.657],[2.196,7.412]],"v":[[-37.786,0.178],[-47.85,-10.355],[-45.32,-25.959],[-34.835,-16.242]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[4.074,-1.656],[2.339,7.412],[-4.074,1.656],[-2.339,-7.412]],"o":[[-4.075,1.657],[-2.339,-7.412],[4.075,-1.657],[2.339,7.412]],"v":[[-36.739,-0.057],[-47.459,-10.59],[-44.763,-26.193],[-33.597,-16.477]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[4.275,-1.656],[2.455,7.412],[-4.275,1.656],[-2.455,-7.412]],"o":[[-4.277,1.657],[-2.455,-7.412],[4.277,-1.657],[2.455,7.412]],"v":[[-35.135,-0.057],[-46.384,-10.59],[-43.555,-26.193],[-31.837,-16.477]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[4.505,-1.656],[2.587,7.412],[-4.505,1.656],[-2.587,-7.412]],"o":[[-4.507,1.657],[-2.587,-7.412],[4.507,-1.657],[2.587,7.412]],"v":[[-33.299,-0.057],[-46.143,-10.478],[-42.667,-26.898],[-29.823,-16.477]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[4.598,-1.656],[2.64,7.412],[-4.598,1.656],[-2.64,-7.412]],"o":[[-4.6,1.657],[-2.64,-7.412],[4.6,-1.657],[2.64,7.412]],"v":[[-32.558,-0.057],[-45.667,-10.478],[-42.12,-26.898],[-29.011,-16.477]],"c":true}]},{"t":135,"s":[{"i":[[4.598,-1.656],[2.64,7.412],[-4.598,1.656],[-2.64,-7.412]],"o":[[-4.6,1.657],[-2.64,-7.412],[4.6,-1.657],[2.64,7.412]],"v":[[-32.206,-0.025],[-45.315,-10.446],[-41.768,-26.866],[-28.659,-16.445]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.678431391716,0.403921574354,0.305882364511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.996,145.54],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Head","np":4,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[1.662,-1.078],[0.252,-6.5],[0,0],[0,0],[0.006,7.75]],"o":[[-1.809,1.173],[-0.012,11],[0,0],[0,0],[-0.448,-10.219]],"v":[[214.31,197.746],[210.645,231.218],[210.632,265.093],[217.136,244.459],[217.174,217.753]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[4.038,-1.078],[0.613,-6.5],[0,0],[0,0],[0.015,7.75]],"o":[[-4.394,1.173],[-0.03,11],[0,0],[0,0],[-1.088,-10.219]],"v":[[219.157,197.746],[210.255,231.218],[210.225,265.093],[226.024,244.459],[226.116,217.753]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[10.281,-1.078],[1.561,-6.5],[0,0],[0,0],[0.038,7.75]],"o":[[-11.186,1.173],[-0.076,11],[0,0],[0,0],[-2.771,-10.219]],"v":[[231.439,197.746],[208.774,231.218],[208.698,265.093],[248.922,244.459],[249.155,217.753]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[16.589,-1.078],[2.519,-6.5],[0,0],[0,0],[0.061,7.75]],"o":[[-18.049,1.173],[-0.123,11],[0,0],[0,0],[-6.41,-10.783]],"v":[[241.968,198.682],[206.53,231.218],[206.407,265.093],[271.689,247.502],[271.688,217.753]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[22.236,-1.078],[3.376,-6.5],[0,0],[0,0],[0.082,7.75]],"o":[[-24.192,1.173],[-0.165,11],[0,0],[0,0],[-8.592,-10.783]],"v":[[251.88,199.385],[204.38,231.218],[204.215,265.093],[291.799,250.781],[291.744,219.393]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[25.614,-1.078],[3.889,-6.5],[0,0],[0,0],[0.095,7.75]],"o":[[-27.868,1.173],[-0.19,11],[0,0],[0,0],[-9.898,-10.783]],"v":[[257.047,200.557],[202.871,231.218],[202.681,265.093],[303.634,253.83],[303.602,221.269]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[28.076,-1.078],[4.263,-6.5],[0,0],[0,0],[0.104,7.75]],"o":[[-30.546,1.173],[-0.208,11],[0,0],[0,0],[-11.853,-12.5]],"v":[[259.05,201.261],[201.981,231.218],[201.773,265.093],[312.516,256.879],[312.499,222.442]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":107.5,"s":[{"i":[[29.015,0],[4.541,-6.5],[0,0],[0,0],[0.111,7.75]],"o":[[-32.559,0],[-0.221,11],[0,0],[0,0],[-12.625,-12.5]],"v":[[263.029,201.731],[201.994,231.218],[201.773,265.093],[319.85,258.99],[319.818,224.789]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[30.448,0],[4.765,-6.5],[0,0],[0,0],[0.116,7.75]],"o":[[-34.167,0],[-0.232,11],[0,0],[0,0],[-13.249,-12.5]],"v":[[265.316,202.435],[202.005,231.218],[201.773,265.093],[325.671,261.572],[325.765,226.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[32.089,0],[5.021,-6.5],[0,0],[0,0],[0.122,7.75]],"o":[[-36.008,0],[-0.245,11],[0,0],[0,0],[-13.962,-12.5]],"v":[[268.491,203.374],[202.018,231.218],[201.773,265.093],[332.444,263.215],[332.444,228.779]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[32.75,0],[5.125,-6.5],[0,0],[0,0],[0.125,7.75]],"o":[[-36.75,0],[-0.25,11],[0,0],[0,0],[-14.25,-12.5]],"v":[[269.148,203.843],[202.023,231.218],[201.773,265.093],[335.023,265.093],[335.023,229.718]],"c":true}]},{"t":135,"s":[{"i":[[32.75,0],[5.125,-6.5],[0,0],[0,0],[0.125,7.75]],"o":[[-36.75,0],[-0.25,11],[0,0],[0,0],[-14.25,-12.5]],"v":[[269.5,203.875],[202.375,231.25],[202.125,265.125],[335.375,265.125],[335.375,229.75]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105865478516,0.450958251953,0.901947021484,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":86,"op":660,"st":60,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"FRONT_SCREEN 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":93.334,"s":[0]},{"t":101.666015625,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0.25,-9.25],[0,0],[0.25,-0.5],[0,0],[0.5,9.25],[0,0],[-2,-2.5],[0,0]],"o":[[0,0],[0.25,3],[0,0],[-2,2.75],[0,0],[0,-16.016],[0,0],[1.75,3.5]],"v":[[-308,-465.5],[-308,477.25],[-308.25,483],[-356.25,568.25],[-364,573.75],[-364,-560.5],[-354.5,-565],[-310.5,-483]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88.334,"s":[{"i":[[1,-13],[0,0],[5,-5],[0,0],[0,16.016],[0,0],[-18,-17],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-11.25,9],[0,0],[0,-16.016],[0,0],[5.5,4.5]],"v":[[-257,-464],[-257,468],[-270.5,493.062],[-345.5,568.5],[-358.25,553.75],[-357,-542.5],[-338,-559],[-265.5,-485.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":89.166,"s":[{"i":[[0.667,-14.005],[0,0],[8.672,-3.333],[0,0],[0,16.016],[0,0],[-17.339,-11.333],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-12.839,6],[0,0],[0,-16.016],[0,0],[9.005,3]],"v":[[-210.667,-462.333],[-210.667,466],[-229.333,495.708],[-334.833,568.667],[-353,549.167],[-352.167,-541.5],[-329.833,-562.167],[-226,-489.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0.333,-15.011],[0,0],[12.344,-1.667],[0,0],[0,16.016],[0,0],[-16.677,-5.667],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-14.427,3],[0,0],[0,-16.016],[0,0],[12.511,1.5]],"v":[[-167.833,-460.667],[-167.833,464],[-191.667,498.354],[-324.167,568.833],[-347.75,544.583],[-347.333,-540.5],[-321.667,-565.333],[-190,-493.833]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-127,-459],[-127,462],[-156,501],[-313.5,569],[-342.5,540],[-342.5,-539.5],[-313.5,-568.5],[-156,-498]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-89.667,-464.667],[-89.667,467.333],[-118.667,503],[-308.667,571.333],[-337.667,542.333],[-337.667,-541.333],[-308.667,-570.333],[-118.667,-500.333]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":92.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-54.833,-470.333],[-54.833,472.667],[-83.833,505],[-303.833,573.667],[-332.833,544.667],[-332.833,-543.167],[-303.833,-572.167],[-83.833,-502.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-24,-476],[-24,478],[-53,507],[-299,576],[-328,547],[-328,-545],[-299,-574],[-53,-505]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":94.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[6.073,-479.4],[6.073,481.5],[-22.927,510.5],[-297.12,577.1],[-326.12,548.1],[-326.12,-546.2],[-297.12,-575.2],[-22.927,-508.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[32.647,-482.8],[32.647,485],[3.647,514],[-295.24,578.2],[-324.24,549.2],[-324.24,-547.4],[-295.24,-576.4],[3.647,-511.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[57.22,-486.2],[57.22,488.5],[28.22,517.5],[-293.36,579.3],[-322.36,550.3],[-322.36,-548.6],[-293.36,-577.6],[28.22,-515.2]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[79.46,-489.6],[79.46,492],[50.46,521],[-291.48,580.4],[-320.48,551.4],[-320.48,-549.8],[-291.48,-578.8],[50.46,-518.6]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[99.7,-493],[99.7,495.5],[70.7,524.5],[-289.6,581.5],[-318.6,552.5],[-318.6,-551],[-289.6,-580],[70.7,-522]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":99.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[136.58,-499.8],[136.58,502.5],[107.58,531.5],[-285.84,583.7],[-314.84,554.7],[-314.84,-553.4],[-285.84,-582.4],[107.58,-528.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[179.4,-510],[179.4,513],[150.4,542],[-280.2,587],[-309.2,558],[-309.2,-557],[-280.2,-586],[150.4,-539]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":103.334,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[201.28,-516],[201.28,518.8],[172.28,547.8],[-279.44,588.2],[-308.44,559.2],[-308.44,-558],[-279.44,-587],[172.28,-545]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[212.053,-519],[212.053,521.7],[183.053,550.7],[-279.06,588.8],[-308.06,559.8],[-308.06,-558.5],[-279.06,-587.5],[183.053,-548]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[220.827,-522],[220.827,524.6],[191.827,553.6],[-278.68,589.4],[-307.68,560.4],[-307.68,-559],[-278.68,-588],[191.827,-551]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[229.1,-525],[229.1,527.5],[200.1,556.5],[-278.3,590],[-307.3,561],[-307.3,-559.5],[-278.3,-588.5],[200.1,-554]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":109.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[256.46,-535.4],[256.46,537.5],[227.46,566.5],[-276.78,592.4],[-305.78,563.4],[-305.78,-561.5],[-276.78,-590.5],[227.46,-564.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":110,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[260.8,-538],[260.8,540],[231.8,569],[-276.4,593],[-305.4,564],[-305.4,-562],[-276.4,-591],[231.8,-567]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":112.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[273.82,-543.7],[273.82,546],[244.82,575],[-276.16,594.2],[-305.16,565.2],[-305.16,-562.6],[-276.16,-591.6],[244.82,-572.7]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":114.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[280.833,-547.5],[280.833,550],[251.833,579],[-276,595],[-305,566],[-305,-563],[-276,-592],[251.833,-576.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[294.867,-555],[294.867,558],[265.867,587],[-275.6,597],[-304.6,568],[-304.6,-564],[-275.6,-593],[265.867,-584]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":122.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[301.9,-559.5],[301.9,563],[272.9,592],[-275.7,597],[-304.7,568],[-304.7,-565],[-275.7,-594],[272.9,-588.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[306.933,-564],[306.933,568],[277.933,597],[-275.8,597],[-304.8,568],[-304.8,-566],[-275.8,-595],[277.933,-593]],"c":true}]},{"t":135,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[310,-568],[310,570],[281,599],[-276,599],[-305,570],[-305,-568],[-276,-597],[281,-597]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.815686285496,0.882352948189,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[384,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[101.75,101.75],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":87,"op":342,"st":60,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"FRONT_SCREEN 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0.25,-9.25],[0,0],[0.25,-0.5],[0,0],[0.5,9.25],[0,0],[-2,-2.5],[0,0]],"o":[[0,0],[0.25,3],[0,0],[-2,2.75],[0,0],[0,-16.016],[0,0],[1.75,3.5]],"v":[[-308,-465.5],[-308,477.25],[-308.25,483],[-356.25,568.25],[-364,573.75],[-364,-560.5],[-354.5,-565],[-310.5,-483]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88.334,"s":[{"i":[[1,-13],[0,0],[5,-5],[0,0],[0,16.016],[0,0],[-18,-17],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-11.25,9],[0,0],[0,-16.016],[0,0],[5.5,4.5]],"v":[[-257,-464],[-257,468],[-270.5,493.062],[-345.5,568.5],[-358.25,553.75],[-357,-542.5],[-338,-559],[-265.5,-485.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":89.166,"s":[{"i":[[0.667,-14.005],[0,0],[8.672,-3.333],[0,0],[0,16.016],[0,0],[-17.339,-11.333],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-12.839,6],[0,0],[0,-16.016],[0,0],[9.005,3]],"v":[[-210.667,-462.333],[-210.667,466],[-229.333,495.708],[-334.833,568.667],[-353,549.167],[-352.167,-541.5],[-329.833,-562.167],[-226,-489.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0.333,-15.011],[0,0],[12.344,-1.667],[0,0],[0,16.016],[0,0],[-16.677,-5.667],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-14.427,3],[0,0],[0,-16.016],[0,0],[12.511,1.5]],"v":[[-167.833,-460.667],[-167.833,464],[-191.667,498.354],[-324.167,568.833],[-347.75,544.583],[-347.333,-540.5],[-321.667,-565.333],[-190,-493.833]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-127,-459],[-127,462],[-156,501],[-313.5,569],[-342.5,540],[-342.5,-539.5],[-313.5,-568.5],[-156,-498]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-89.667,-464.667],[-89.667,467.333],[-118.667,503],[-308.667,571.333],[-337.667,542.333],[-337.667,-541.333],[-308.667,-570.333],[-118.667,-500.333]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":92.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-54.833,-470.333],[-54.833,472.667],[-83.833,505],[-303.833,573.667],[-332.833,544.667],[-332.833,-543.167],[-303.833,-572.167],[-83.833,-502.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[-24,-476],[-24,478],[-53,507],[-299,576],[-328,547],[-328,-545],[-299,-574],[-53,-505]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":94.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[6.073,-479.4],[6.073,481.5],[-22.927,510.5],[-297.12,577.1],[-326.12,548.1],[-326.12,-546.2],[-297.12,-575.2],[-22.927,-508.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[32.647,-482.8],[32.647,485],[3.647,514],[-295.24,578.2],[-324.24,549.2],[-324.24,-547.4],[-295.24,-576.4],[3.647,-511.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[57.22,-486.2],[57.22,488.5],[28.22,517.5],[-293.36,579.3],[-322.36,550.3],[-322.36,-548.6],[-293.36,-577.6],[28.22,-515.2]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":96.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[79.46,-489.6],[79.46,492],[50.46,521],[-291.48,580.4],[-320.48,551.4],[-320.48,-549.8],[-291.48,-578.8],[50.46,-518.6]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[99.7,-493],[99.7,495.5],[70.7,524.5],[-289.6,581.5],[-318.6,552.5],[-318.6,-551],[-289.6,-580],[70.7,-522]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":99.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[136.58,-499.8],[136.58,502.5],[107.58,531.5],[-285.84,583.7],[-314.84,554.7],[-314.84,-553.4],[-285.84,-582.4],[107.58,-528.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.666,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[179.4,-510],[179.4,513],[150.4,542],[-280.2,587],[-309.2,558],[-309.2,-557],[-280.2,-586],[150.4,-539]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":103.334,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[201.28,-516],[201.28,518.8],[172.28,547.8],[-279.44,588.2],[-308.44,559.2],[-308.44,-558],[-279.44,-587],[172.28,-545]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":104.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[212.053,-519],[212.053,521.7],[183.053,550.7],[-279.06,588.8],[-308.06,559.8],[-308.06,-558.5],[-279.06,-587.5],[183.053,-548]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[220.827,-522],[220.827,524.6],[191.827,553.6],[-278.68,589.4],[-307.68,560.4],[-307.68,-559],[-278.68,-588],[191.827,-551]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.834,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[229.1,-525],[229.1,527.5],[200.1,556.5],[-278.3,590],[-307.3,561],[-307.3,-559.5],[-278.3,-588.5],[200.1,-554]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":109.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[256.46,-535.4],[256.46,537.5],[227.46,566.5],[-276.78,592.4],[-305.78,563.4],[-305.78,-561.5],[-276.78,-590.5],[227.46,-564.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":110,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[260.8,-538],[260.8,540],[231.8,569],[-276.4,593],[-305.4,564],[-305.4,-562],[-276.4,-591],[231.8,-567]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":112.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[273.82,-543.7],[273.82,546],[244.82,575],[-276.16,594.2],[-305.16,565.2],[-305.16,-562.6],[-276.16,-591.6],[244.82,-572.7]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":114.166,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[280.833,-547.5],[280.833,550],[251.833,579],[-276,595],[-305,566],[-305,-563],[-276,-592],[251.833,-576.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118.334,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[294.867,-555],[294.867,558],[265.867,587],[-275.6,597],[-304.6,568],[-304.6,-564],[-275.6,-593],[265.867,-584]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":122.5,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[301.9,-559.5],[301.9,563],[272.9,592],[-275.7,597],[-304.7,568],[-304.7,-565],[-275.7,-594],[272.9,-588.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[306.933,-564],[306.933,568],[277.933,597],[-275.8,597],[-304.8,568],[-304.8,-566],[-275.8,-595],[277.933,-593]],"c":true}]},{"t":135,"s":[{"i":[[0,-16.016],[0,0],[16.016,0],[0,0],[0,16.016],[0,0],[-16.016,0],[0,0]],"o":[[0,0],[0,16.016],[0,0],[-16.016,0],[0,0],[0,-16.016],[0,0],[16.016,0]],"v":[[310,-568],[310,570],[281,599],[-276,599],[-305,570],[-305,-568],[-276,-597],[281,-597]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[384,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[101.75,101.75],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":87,"op":342,"st":60,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"CENTER_SCREEN 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[699,-539],[699,539],[653,585],[-0.999,585],[-653,585],[-699,539],[-699,-539],[-653,-585],[1,-585],[653,-585]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.166,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[707,-547],[707,547],[661,593],[-0.999,585],[-639.273,577],[-685.273,531],[-685.273,-527],[-639.273,-573],[1,-585],[661,-593]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.334,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[715,-563],[715,567],[669,613],[-0.999,585],[-617.545,561],[-663.545,515],[-663.545,-511],[-617.545,-557],[1,-585],[669,-609]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70.834,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[709,-577.4],[709,579],[663,625],[-0.999,585],[-587.709,551.4],[-636.709,505.4],[-636.709,-501.4],[-587.709,-547.4],[1,-585],[663,-623.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":72.5,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[705,-587],[705,587],[659,633],[-0.999,585],[-567.818,545],[-613.818,499],[-613.818,-495],[-567.818,-541],[1,-585],[659,-633]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73.334,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[697.4,-593.4],[697.4,595],[651.4,641],[-0.999,585],[-553.873,539.4],[-599.873,493.4],[-599.873,-490.2],[-553.873,-536.2],[1,-585],[651.4,-639.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":74.166,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[693.8,-599.8],[693.8,603],[647.8,649],[-0.999,585],[-537.927,533.8],[-583.927,487.8],[-583.927,-485.4],[-537.927,-531.4],[1,-585],[647.8,-645.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[678.2,-606.2],[678.2,611],[632.2,657],[-0.999,585],[-519.982,528.2],[-565.982,482.2],[-565.982,-480.6],[-519.982,-526.6],[1,-585],[632.2,-652.2]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75.834,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[666.6,-612.6],[666.6,619],[620.6,665],[-0.999,585],[-499.036,522.6],[-545.036,476.6],[-545.036,-475.8],[-499.036,-521.8],[1,-585],[620.6,-658.6]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.405,0],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-25.405,0],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[647,-619],[647,627],[601,673],[-0.999,585],[-478.091,517],[-524.091,471],[-524.091,-471],[-478.091,-517],[1,-585],[601,-665]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":78.334,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.223,2.5],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-22.441,-1.8],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[600.891,-638.2],[600.891,649.545],[561.618,691.182],[-5.908,586.273],[-428.856,507],[-467.174,466.273],[-467.174,-463],[-420.674,-508.5],[1,-585.6],[554.891,-684.2]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79.166,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.132,3.75],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-20.96,-2.7],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[561.836,-647.8],[561.836,660.818],[525.927,700.273],[-8.363,586.909],[-398.739,502],[-433.216,463.909],[-433.216,-459],[-386.466,-504.25],[1,-585.9],[515.836,-693.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-25.041,5],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-19.478,-3.6],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[522.782,-657.4],[522.782,672.091],[490.236,709.364],[-10.817,587.546],[-368.621,497],[-399.258,461.546],[-399.258,-455],[-352.258,-500],[1,-586.2],[476.782,-703.4]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80.834,"s":[{"i":[[0,-25.405],[0,0],[25.405,0],[0,0],[0,0],[0,25.405],[0,0],[-24.95,6.25],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-17.996,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[25.405,0]],"v":[[471.727,-667],[471.727,683.364],[442.545,718.455],[-13.272,588.182],[-332.504,492],[-359.3,459.182],[-359.3,-451],[-312.05,-495.75],[1,-586.5],[425.727,-713]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[0.129,-24.588],[0,0],[21.663,1.508],[0,0],[0,0],[0.008,23.224],[0,0],[-21.2,5.875],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-15.329,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[21.8,-2.083]],"v":[[412.352,-679.333],[412.352,694.197],[387.295,726.538],[-16.188,588.015],[-289.754,488.25],[-312.675,457.182],[-312.675,-449],[-272.55,-491.375],[-4.583,-587],[372.894,-720.667]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.5,"s":[{"i":[[0.258,-23.77],[0,0],[17.922,3.015],[0,0],[0,0],[0.017,21.043],[0,0],[-17.45,5.5],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-12.663,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[18.194,-4.167]],"v":[[344.977,-691.667],[344.977,705.03],[324.045,734.621],[-19.105,587.849],[-247.004,484.5],[-266.05,455.182],[-266.05,-447],[-233.05,-487],[-10.166,-587.5],[312.06,-728.333]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[0.386,-22.953],[0,0],[14.18,4.523],[0,0],[0,0],[0.025,18.862],[0,0],[-13.7,5.125],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-9.996,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[14.589,-6.25]],"v":[[269.602,-704],[269.602,715.864],[252.795,742.705],[-22.022,587.682],[-204.254,480.75],[-219.425,453.182],[-219.425,-445],[-193.55,-482.625],[-15.75,-588],[243.227,-736]],"c":true}]},{"t":85.833984375,"s":[{"i":[[0.773,-20.5],[0,0],[2.955,9.045],[0,0],[0,0],[0.05,12.318],[0,0],[-2.45,4],[0,0],[0,0]],"o":[[0,0],[0,25.405],[0,0],[0,0],[-1.996,-4.5],[0,0],[0,-25.405],[0,0],[0,0],[3.773,-12.5]],"v":[[13.477,-707],[13.477,713.364],[9.045,731.955],[-30.772,587.182],[-58.004,481.5],[-61.55,459.182],[-61.55,-451],[-57.05,-481.5],[-32.5,-581.5],[6.727,-725]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-3,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":87,"st":60,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"FOLDABLE_BODY 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.312,149.969,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.95,19.95,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,-40.869],[0,0],[40.869,0],[0,0],[0,0],[0,40.869],[0,0],[-40.869,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[-40.869,0],[0,0],[0,-40.869],[0,0],[0,0],[40.869,0]],"v":[[733,-567],[733,567],[659,641],[5,643],[-659,641],[-733,567],[-733,-567],[-659,-641],[3.001,-641],[659,-641]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65,"s":[{"i":[[0,-40.869],[0,0],[40.869,0],[0,0],[0,0],[-0.091,49.495],[0,0],[-40.869,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[-46.341,0.245],[0,0],[-1.795,-49.895],[0,0],[0,0],[40.869,0]],"v":[[748.332,-581.845],[747.391,584.136],[673.391,658.136],[5,644.125],[-640.409,628.505],[-714.409,554.505],[-714.455,-550.855],[-640.455,-627.105],[3.001,-643.25],[674.332,-655.845]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":69.166,"s":[{"i":[[0,-40.869],[0,0],[40.869,0],[0,0],[0,0],[0,40.869],[0,0],[-40.869,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[-40.869,0],[0,0],[0,-40.869],[0,0],[0,0],[40.869,0]],"v":[[755.15,-598.8],[754.8,603],[680.8,677],[5,643],[-610.25,613.05],[-684.25,539.05],[-685.25,-537.4],[-611.25,-611.4],[3.001,-641],[681.15,-672.8]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70.834,"s":[{"i":[[0,-40.869],[0,0],[42.179,0.978],[0,0],[0,0],[0,40.869],[0,0],[-43.221,1.138],[0,0],[0,0]],"o":[[0,0],[-0.542,42.899],[0,0],[0,0],[-46.299,-2.698],[0,0],[0,-40.869],[0,0],[0,0],[40.869,0]],"v":[[752.228,-610.767],[752.022,614.022],[675.022,688.422],[5,642.2],[-587.372,604.128],[-663.797,530.128],[-665.175,-528.378],[-588.75,-602.378],[3.001,-641],[678.228,-684.767]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73.334,"s":[{"i":[[0,-40.869],[0,0],[44.144,2.444],[0,0],[0,0],[0,40.869],[0,0],[-46.75,2.844],[0,0],[0,0]],"o":[[0,0],[-1.356,45.944],[0,0],[0,0],[-54.444,-6.745],[0,0],[0,-40.869],[0,0],[0,0],[40.869,0]],"v":[[747.844,-628.717],[747.856,630.556],[666.356,705.556],[5,641],[-553.056,590.745],[-625.618,516.745],[-627.562,-514.844],[-555,-588.844],[3.001,-641],[673.844,-702.717]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,-40.869],[0,0],[42.507,1.222],[0,0],[0,0],[0,40.869],[0,0],[-50.375,3.922],[0,0],[0,0]],"o":[[0,0],[-0.678,43.407],[0,0],[0,0],[-54.222,-7.622],[0,0],[0,-40.869],[0,0],[0,0],[46.435,-1.875]],"v":[[734.172,-645.858],[734.428,648.778],[650.678,723.278],[5,642.75],[-513.528,581.122],[-590.559,507.372],[-591.531,-504.922],[-514.5,-578.922],[3.001,-641.875],[649.172,-720.233]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76.666,"s":[{"i":[[0,-40.869],[0,0],[40.869,0],[0,0],[0,0],[0,40.869],[0,0],[-54,5],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[-54,-8.5],[0,0],[0,-40.869],[0,0],[0,0],[52,-3.75]],"v":[[708.5,-663],[709,667],[635,741],[5,644.5],[-474,571.5],[-545.5,498],[-545.5,-495],[-474,-569],[3.001,-642.75],[624.5,-737.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":79.166,"s":[{"i":[[0.9,-49.498],[0,0],[45.297,5.4],[0,0],[0,0],[0,40.869],[0,0],[-40.05,6.8],[0,0],[0,0]],"o":[[0,0],[0.3,47.208],[0,0],[0,0],[-39.15,-8.5],[0,0],[-0.3,-34.008],[0,0],[0,0],[52.45,-11.925]],"v":[[636.05,-692.05],[634.9,699.675],[545.45,770.9],[-7.675,640.525],[-400.05,552.55],[-455.15,479.65],[-453.6,-480.1],[-404,-549.2],[-14.199,-644.325],[537.55,-767.925]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":80.834,"s":[{"i":[[1.5,-55.25],[0,0],[48.25,9],[0,0],[0,0],[0,40.869],[0,0],[-30.75,8],[0,0],[0,0]],"o":[[0,0],[0.5,51.435],[0,0],[0,0],[-29.25,-8.5],[0,0],[-0.5,-29.435],[0,0],[0,0],[52.75,-17.375]],"v":[[549,-717.25],[549.25,723.125],[453.25,792.5],[-16.125,637.875],[-330.75,540.75],[-370.75,480.75],[-372.75,-481],[-331.5,-538.5],[-21.499,-639.125],[448.75,-787.625]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":81.666,"s":[{"i":[[2.15,-55.283],[0,0],[43.55,12.75],[0,0],[0,0],[-0.25,36.729],[0,0],[-24.85,7.933],[0,0],[0,0]],"o":[[0,0],[1.8,55.206],[0,0],[0,0],[-23.033,-8.15],[0,0],[-0.6,-27.148],[0,0],[0,0],[50.633,-18.367]],"v":[[493.267,-729.3],[493.367,733.5],[388.433,800.9],[-21.017,638.133],[-291.55,534.233],[-324,473.767],[-324.933,-478.317],[-290.983,-532.1],[-25.783,-636.917],[386.317,-797.433]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.5,"s":[{"i":[[2.8,-55.317],[0,0],[38.85,16.5],[0,0],[0,0],[-0.5,32.59],[0,0],[-18.95,7.867],[0,0],[0,0]],"o":[[0,0],[3.1,58.978],[0,0],[0,0],[-16.817,-7.8],[0,0],[-0.7,-24.861],[0,0],[0,0],[48.517,-19.358]],"v":[[427.533,-741.35],[427.483,743.875],[323.617,809.3],[-25.908,638.392],[-252.35,527.717],[-277.25,466.783],[-277.117,-475.633],[-250.467,-525.7],[-30.066,-634.708],[323.883,-807.242]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":83.334,"s":[{"i":[[3.45,-55.35],[0,0],[34.15,20.25],[0,0],[0,0],[-0.75,28.45],[0,0],[-13.05,7.8],[0,0],[0,0]],"o":[[0,0],[4.4,62.75],[0,0],[0,0],[-10.6,-7.45],[0,0],[-0.8,-22.574],[0,0],[0,0],[46.4,-20.35]],"v":[[351.8,-753.4],[351.6,754.25],[258.8,817.7],[-30.8,638.65],[-213.15,521.2],[-230.5,459.8],[-229.3,-472.95],[-209.95,-519.3],[-34.349,-632.5],[261.45,-817.05]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":84.166,"s":[{"i":[[3.225,-52.425],[0,0],[29.45,24],[0,0],[0,0],[-0.375,34.66],[0,0],[-10.275,9.4],[0,0],[0,0]],"o":[[0,0],[2.7,62.375],[0,0],[0,0],[-7.55,-7.975],[0,0],[-0.9,-20.287],[0,0],[0,0],[45.7,-22.425]],"v":[[269.9,-765.45],[269.55,764.625],[176.9,819.85],[-34.025,634.95],[-163.325,517.6],[-176.25,463.65],[-175.65,-472.975],[-160.475,-516.65],[-39.674,-626.75],[180.475,-821.025]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85,"s":[{"i":[[3,-49.5],[0,0],[24.75,27.75],[0,0],[0,0],[0,40.869],[0,0],[-7.5,11],[0,0],[0,0]],"o":[[0,0],[1,62],[0,0],[0,0],[-4.5,-8.5],[0,0],[-1,-18],[0,0],[0,0],[45,-24.5]],"v":[[182,-777.5],[181.5,775],[95,822],[-37.25,631.25],[-113.5,514],[-122,467.5],[-122,-473],[-111,-514],[-44.999,-621],[99.5,-825]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":85.834,"s":[{"i":[[2.115,-52.053],[0,0],[14.076,24.655],[0,0],[0,0],[0.15,39.565],[0,0],[-4.448,8.548],[0,0],[0,0]],"o":[[0,0],[-2.465,27.536],[0,0],[0,0],[-2.458,-8.114],[0,0],[-0.9,-26.528],[0,0],[0,0],[26.131,-22.782]],"v":[[89.385,-789.28],[89.465,814.464],[14.257,825.512],[-39.14,629.206],[-64.364,505.574],[-68.567,459.152],[-66.85,-455.222],[-64.968,-503.548],[-33.506,-639.074],[16.369,-824.885]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":86.666,"s":[{"i":[[0.346,-57.159],[0,0],[-7.272,18.464],[0,0],[0,0],[0.451,36.956],[0,0],[1.656,3.645],[0,0],[0,0]],"o":[[0,0],[0.605,52.109],[0,0],[0,0],[1.626,-7.341],[0,0],[-0.7,-43.583],[0,0],[0,0],[-11.608,-19.345]],"v":[[-77.846,-794.841],[-76.605,801.391],[5.772,824.536],[14.08,628.118],[25.909,512.723],[30.299,466.457],[32.45,-470.667],[16.094,-533.645],[13.482,-630.223],[3.108,-827.655]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":87.5,"s":[{"i":[[0.346,-57.159],[0,0],[-7.272,18.464],[0,0],[0,0],[0.451,36.956],[0,0],[1.656,3.645],[0,0],[0,0]],"o":[[0,0],[0.605,52.109],[0,0],[0,0],[1.626,-7.341],[0,0],[-0.7,-43.583],[0,0],[0,0],[-11.608,-19.345]],"v":[[-161.846,-788.841],[-160.605,797.391],[-78.228,820.536],[14.08,628.118],[75.909,512.723],[80.299,466.457],[82.45,-470.667],[66.094,-533.645],[13.482,-630.223],[-80.892,-821.655]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":88.334,"s":[{"i":[[0.679,-54.879],[0,0],[-13.362,17.618],[0,0],[0,0],[0.601,35.652],[0,0],[2.96,5.097],[0,0],[0,0]],"o":[[0,0],[0.139,54.646],[0,0],[0,0],[3.668,-6.954],[0,0],[-0.709,-37.134],[0,0],[0,0],[-28.144,-20.461]],"v":[[-243.346,-774.288],[-241.973,784.854],[-150.304,818.382],[12.523,630.074],[120.379,515.297],[132.565,465.957],[134.267,-469.042],[115.459,-527.361],[14.143,-629.964],[-152.023,-818.206]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":89.166,"s":[{"i":[[1.012,-52.598],[0,0],[-19.453,16.773],[0,0],[0,0],[0.752,34.347],[0,0],[4.265,6.548],[0,0],[0,0]],"o":[[0,0],[-0.326,57.182],[0,0],[0,0],[5.71,-6.568],[0,0],[-0.718,-30.686],[0,0],[0,0],[-44.68,-21.576]],"v":[[-317.846,-759.735],[-316.341,772.318],[-229.381,816.227],[10.967,632.03],[164.848,517.871],[180.831,465.457],[182.083,-467.416],[164.824,-521.076],[14.803,-629.705],[-230.153,-814.758]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[1.346,-50.318],[0,0],[-25.543,15.927],[0,0],[0,0],[0.902,33.043],[0,0],[5.57,8],[0,0],[0,0]],"o":[[0,0],[-0.791,59.718],[0,0],[0,0],[7.752,-6.182],[0,0],[-0.727,-24.237],[0,0],[0,0],[-61.216,-22.691]],"v":[[-385.346,-745.182],[-383.709,759.782],[-294.457,814.073],[9.41,633.986],[209.318,520.445],[226.598,464.957],[227.4,-465.791],[214.189,-514.791],[15.464,-629.445],[-294.284,-811.309]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90.834,"s":[{"i":[[1.418,-49.133],[0,0],[-31.384,13.082],[0,0],[0,0],[0.677,35],[0,0],[7.748,7.5],[0,0],[0,0]],"o":[[0,0],[-0.457,57.887],[0,0],[0,0],[9.794,-5.795],[0,0],[-0.682,-25.276],[0,0],[0,0],[-56.377,-19.098]],"v":[[-443.237,-737.295],[-442.077,748.496],[-351.866,806.918],[10.729,633.609],[244.163,523.811],[267.781,467.033],[268.3,-467.923],[248.074,-518.673],[13.874,-629.811],[-352.623,-804.027]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":91.666,"s":[{"i":[[1.491,-47.948],[0,0],[-37.224,10.236],[0,0],[0,0],[0.451,36.956],[0,0],[9.927,7],[0,0],[0,0]],"o":[[0,0],[-0.123,56.057],[0,0],[0,0],[11.836,-5.409],[0,0],[-0.636,-26.316],[0,0],[0,0],[-51.538,-15.505]],"v":[[-496.127,-729.409],[-495.445,737.209],[-404.276,799.764],[12.047,633.232],[279.007,527.177],[306.964,469.109],[307.2,-470.055],[281.96,-522.555],[12.285,-630.177],[-405.962,-796.745]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":92.5,"s":[{"i":[[1.564,-46.762],[0,0],[-43.065,7.391],[0,0],[0,0],[0.226,38.913],[0,0],[12.105,6.5],[0,0],[0,0]],"o":[[0,0],[0.211,54.226],[0,0],[0,0],[13.878,-5.023],[0,0],[-0.591,-27.356],[0,0],[0,0],[-46.699,-11.911]],"v":[[-539.018,-721.523],[-538.814,725.923],[-446.685,792.609],[13.365,632.855],[313.852,530.543],[342.647,471.185],[342.6,-472.186],[315.845,-526.436],[10.695,-630.543],[-449.301,-789.464]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93.334,"s":[{"i":[[1.636,-45.577],[0,0],[-48.906,4.545],[0,0],[0,0],[0,40.869],[0,0],[14.283,6],[0,0],[0,0]],"o":[[0,0],[0.545,52.395],[0,0],[0,0],[15.919,-4.636],[0,0],[-0.545,-28.395],[0,0],[0,0],[-41.86,-8.318]],"v":[[-576.909,-713.636],[-577.182,714.636],[-484.094,785.455],[14.684,632.477],[348.697,533.909],[377.33,473.261],[377,-474.318],[349.731,-530.318],[9.106,-630.909],[-487.64,-782.182]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":94.166,"s":[{"i":[[1.5,-45.185],[0,0],[-48.199,4.167],[0,0],[0,0],[0,40.869],[0,0],[16.461,5.5],[0,0],[0,0]],"o":[[0,0],[0.5,51.435],[0,0],[0,0],[17.961,-4.25],[0,0],[-0.5,-29.435],[0,0],[0,0],[-41.74,-7.625]],"v":[[-609.5,-705.25],[-609.25,706.583],[-516.07,777.667],[13.048,633.104],[372.373,539.146],[405.552,476.99],[405.333,-478.125],[373.571,-535.625],[8.099,-632],[-520.404,-774.333]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":95.834,"s":[{"i":[[1.227,-44.4],[0,0],[-46.785,3.409],[0,0],[0,0],[0,40.869],[0,0],[20.818,4.5],[0,0],[0,0]],"o":[[0,0],[0.409,49.514],[0,0],[0,0],[22.045,-3.477],[0,0],[-0.409,-31.514],[0,0],[0,0],[-41.501,-6.239]],"v":[[-659.682,-688.477],[-658.386,690.477],[-565.023,762.091],[9.776,634.358],[419.724,549.619],[461.997,484.446],[462,-485.739],[421.25,-546.239],[6.087,-634.182],[-570.932,-758.636]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":97.5,"s":[{"i":[[0.955,-43.615],[0,0],[-45.371,2.652],[0,0],[0,0],[0,40.869],[0,0],[25.175,3.5],[0,0],[0,0]],"o":[[0,0],[0.318,47.593],[0,0],[0,0],[26.129,-2.705],[0,0],[-0.318,-33.592],[0,0],[0,0],[-41.261,-4.852]],"v":[[-693.197,-672.705],[-692.189,674.705],[-601.975,746.515],[6.505,635.612],[457.076,558.093],[507.109,489.902],[506.667,-490.686],[457.596,-554.186],[4.075,-633.03],[-608.126,-744.273]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":98.334,"s":[{"i":[[0.818,-43.223],[0,0],[-44.664,2.273],[0,0],[0,0],[0,40.869],[0,0],[27.353,3],[0,0],[0,0]],"o":[[0,0],[0.273,46.632],[0,0],[0,0],[28.171,-2.318],[0,0],[-0.273,-34.632],[0,0],[0,0],[-41.142,-4.159]],"v":[[-705.455,-664.818],[-704.591,666.818],[-615.951,738.727],[4.869,636.239],[475.752,562.33],[526.665,492.631],[526,-493.159],[475.769,-558.159],[3.069,-632.455],[-622.224,-737.091]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100,"s":[{"i":[[0.545,-42.438],[0,0],[-43.251,1.515],[0,0],[0,0],[0,40.869],[0,0],[31.71,2],[0,0],[0,0]],"o":[[0,0],[0.182,44.711],[0,0],[0,0],[32.255,-1.545],[0,0],[-0.182,-36.711],[0,0],[0,0],[-40.902,-2.773]],"v":[[-723.303,-651.879],[-722.727,654.212],[-635.57,726.485],[1.598,637.492],[498.104,569.803],[562.443,499.754],[561.667,-498.773],[497.782,-566.773],[1.056,-632.97],[-643.418,-724.727]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":100.834,"s":[{"i":[[0.409,-42.046],[0,0],[-42.544,1.136],[0,0],[0,0],[0,40.869],[0,0],[33.888,1.5],[0,0],[0,0]],"o":[[0,0],[0.136,43.75],[0,0],[0,0],[34.297,-1.159],[0,0],[-0.136,-37.751],[0,0],[0,0],[-40.782,-2.08]],"v":[[-731.727,-645.409],[-731.295,647.909],[-644.879,720.364],[-0.038,638.119],[509.28,573.54],[577.332,503.315],[576.5,-501.58],[508.788,-571.08],[0.05,-633.227],[-653.516,-718.545]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":101.666,"s":[{"i":[[0.273,-41.654],[0,0],[-41.837,0.758],[0,0],[0,0],[0,40.869],[0,0],[36.066,1],[0,0],[0,0]],"o":[[0,0],[0.091,42.79],[0,0],[0,0],[36.339,-0.773],[0,0],[-0.091,-38.79],[0,0],[0,0],[-40.663,-1.386]],"v":[[-737.152,-638.939],[-736.864,641.606],[-651.189,714.242],[-1.674,638.746],[520.456,577.277],[590.222,506.877],[589.333,-504.386],[519.795,-575.386],[-0.956,-633.485],[-660.613,-712.364]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":103.334,"s":[{"i":[[0,-40.869],[0,0],[-40.423,0],[0,0],[0,0],[0,40.869],[0,0],[40.423,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[40.423,0],[0,0],[0,-40.869],[0,0],[0,0],[-40.423,0]],"v":[[-744,-626],[-744,629],[-659.808,702],[-4.946,640],[542.808,584.75],[616,514],[615,-510],[541.808,-584],[-2.968,-634],[-670.808,-700]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105.834,"s":[{"i":[[0,-40.869],[0,0],[-40.423,0],[0,0],[0,0],[0,40.869],[0,0],[40.423,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[40.423,0],[0,0],[0,-40.869],[0,0],[0,0],[-40.423,0]],"v":[[-744.842,-614.959],[-744.6,619.497],[-661.426,691.301],[-2.779,639.354],[564.646,592.557],[643.41,522.301],[642.956,-517.867],[564.192,-591.867],[-2.968,-634.219],[-671.649,-688.959]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":109.166,"s":[{"i":[[0,-40.869],[0,0],[-40.423,0],[0,0],[0,0],[0,40.869],[0,0],[40.423,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[40.423,0],[0,0],[0,-40.869],[0,0],[0,0],[-40.423,0]],"v":[[-745.964,-600.237],[-745.4,606.826],[-663.584,677.035],[0.11,638.493],[593.764,602.967],[672.957,533.369],[673.23,-528.356],[594.037,-602.356],[-2.968,-634.512],[-672.771,-674.237]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":111.666,"s":[{"i":[[0,-40.869],[0,0],[-40.423,0],[0,0],[0,0],[0,40.869],[0,0],[40.423,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[40.423,0],[0,0],[0,-40.869],[0,0],[0,0],[-40.423,0]],"v":[[-746.806,-589.196],[-746,597.323],[-665.202,666.336],[2.276,637.847],[615.603,610.775],[688.795,541.67],[689.614,-536.222],[616.422,-610.222],[-2.968,-634.731],[-673.613,-663.196]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":118,"s":[{"i":[[0,-40.869],[0,0],[-46.482,1.895],[0,0],[0,0],[0,40.869],[0,0],[40.423,0],[0,0],[0,0]],"o":[[0,0],[-1,44.868],[0,0],[0,0],[40.423,0],[0,0],[-0.105,-46.5],[0,0],[0,0],[-40.423,0]],"v":[[-736,-575.053],[-735,579.632],[-656.018,651.105],[8.054,637.474],[642.439,625.645],[714.632,557.105],[715.105,-550],[641.913,-624],[-2.968,-635.316],[-662.808,-649.053]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":126,"s":[{"i":[[0,-40.869],[0,0],[-44.048,1],[0,0],[0,0],[3,43.078],[0,0],[40.423,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[43.733,1],[0,0],[1.328,-42.15],[0,0],[0,0],[-40.423,0]],"v":[[-725.575,-563.749],[-725.75,566.434],[-649.952,640.197],[0.904,637.851],[657.767,633.903],[730.959,560.672],[730.922,-559.6],[657.73,-633.6],[-2.968,-638.442],[-656.133,-637.749]],"c":true}]},{"t":135,"s":[{"i":[[0,-40.869],[0,0],[-40.423,0],[0,0],[0,0],[0,40.869],[0,0],[40.423,0],[0,0],[0,0]],"o":[[0,0],[0,40.869],[0,0],[0,0],[40.423,0],[0,0],[0,-40.869],[0,0],[0,0],[-40.423,0]],"v":[[-725,-571],[-725.945,569],[-652.753,640],[-5.891,640],[660.862,640],[734.055,569],[735,-571],[661.808,-639],[-2.968,-639],[-651.808,-639]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-3,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":386,"st":60,"bm":10}],"markers":[]}
\ No newline at end of file diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml index 16152f80308a..08e1bf22089e 100644 --- a/packages/SystemUI/res/values-night/colors.xml +++ b/packages/SystemUI/res/values-night/colors.xml @@ -78,9 +78,6 @@ <color name="biometric_dialog_accent">@color/material_dynamic_primary70</color> <color name="biometric_dialog_error">#fff28b82</color> <!-- red 300 --> - <!-- UDFPS colors --> - <color name="udfps_enroll_icon">#7DA7F1</color> - <color name="GM2_green_500">#FF41Af6A</color> <color name="GM2_blue_500">#5195EA</color> <color name="GM2_red_500">#E25142</color> @@ -103,4 +100,13 @@ <color name="accessibility_floating_menu_message_text">@*android:color/primary_text_default_material_dark</color> <color name="people_tile_background">@color/material_dynamic_secondary20</color> + + <!-- UDFPS colors --> + <color name="udfps_enroll_icon">#7DA7F1</color> + <color name="udfps_moving_target_fill">#475670</color> + <!-- 50% of udfps_moving_target_fill--> + <color name="udfps_moving_target_fill_error">#80475670</color> + <color name="udfps_enroll_progress">#7DA7F1</color> + <color name="udfps_enroll_progress_help">#607DA7F1</color> + <color name="udfps_enroll_progress_help_with_talkback">#FFEE675C</color> </resources> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index 44ba3f6e6d86..5b6c9d3643e0 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -209,5 +209,15 @@ <attr name="permissionGrantButtonTopStyle" format="reference"/> <attr name="permissionGrantButtonBottomStyle" format="reference"/> </declare-styleable> + + <declare-styleable name="BiometricsEnrollView"> + <attr name="biometricsEnrollStyle" format="reference" /> + <attr name="biometricsEnrollIcon" format="reference|color" /> + <attr name="biometricsMovingTargetFill" format="reference|color" /> + <attr name="biometricsMovingTargetFillError" format="reference|color" /> + <attr name="biometricsEnrollProgress" format="reference|color" /> + <attr name="biometricsEnrollProgressHelp" format="reference|color" /> + <attr name="biometricsEnrollProgressHelpWithTalkback" format="reference|color" /> + </declare-styleable> </resources> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 6b4bea190977..8ee39dd5963f 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -134,12 +134,12 @@ <color name="biometric_dialog_error">#ffd93025</color> <!-- red 600 --> <!-- UDFPS colors --> - <color name="udfps_enroll_icon">#7DA7F1</color> - <color name="udfps_moving_target_fill">#475670</color> + <color name="udfps_enroll_icon">#699FF3</color> + <color name="udfps_moving_target_fill">#C2D7F7</color> <!-- 50% of udfps_moving_target_fill--> - <color name="udfps_moving_target_fill_error">#80475670</color> - <color name="udfps_enroll_progress">#7DA7F1</color> - <color name="udfps_enroll_progress_help">#607DA7F1</color> + <color name="udfps_moving_target_fill_error">#80C2D7F7</color> + <color name="udfps_enroll_progress">#699FF3</color> + <color name="udfps_enroll_progress_help">#70699FF3</color> <color name="udfps_enroll_progress_help_with_talkback">#FFEE675C</color> <!-- Floating overlay actions --> @@ -257,4 +257,8 @@ <color name="dream_overlay_clock_ambient_text_shadow_color">#4D000000</color> <color name="dream_overlay_status_bar_key_text_shadow_color">#66000000</color> <color name="dream_overlay_status_bar_ambient_text_shadow_color">#59000000</color> + + <!-- Rear Display Education --> + <color name="rear_display_overlay_animation_background_color">#1E1B17</color> + <color name="rear_display_overlay_dialog_background_color">#1E1B17</color> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 67e22483483f..9f29c5bd0bc2 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1177,7 +1177,7 @@ <!-- Screen record dialog --> <dimen name="screenrecord_option_padding">18dp</dimen> - <dimen name="screenrecord_logo_size">26dp</dimen> + <dimen name="screenrecord_logo_size">30dp</dimen> <dimen name="screenrecord_option_icon_size">24dp</dimen> <!-- Screen record status bar icon --> <dimen name="screenrecord_status_text_size">14sp</dimen> @@ -1185,6 +1185,18 @@ <dimen name="screenrecord_status_icon_width">21dp</dimen> <dimen name="screenrecord_status_icon_height">17.5dp</dimen> <dimen name="screenrecord_status_icon_bg_radius">8dp</dimen> + <!-- Screen record spinner --> + <dimen name="screenrecord_spinner_height">72dp</dimen> + <dimen name="screenrecord_spinner_margin">24dp</dimen> + <dimen name="screenrecord_spinner_text_padding_start">20dp</dimen> + <dimen name="screenrecord_spinner_text_padding_end">80dp</dimen> + <dimen name="screenrecord_spinner_arrow_size">24dp</dimen> + <dimen name="screenrecord_spinner_background_radius">28dp</dimen> + + <dimen name="screenrecord_title_margin_top">20dp</dimen> + <dimen name="screenrecord_warning_line_height">20dp</dimen> + <dimen name="screenrecord_options_padding_bottom">16dp</dimen> + <dimen name="screenrecord_buttons_margin_top">20dp</dimen> <!-- Keyguard user switcher --> <dimen name="kg_user_switcher_text_size">16sp</dimen> @@ -1611,4 +1623,10 @@ <dimen name="config_rounded_mask_size">0px</dimen> <dimen name="config_rounded_mask_size_top">0px</dimen> <dimen name="config_rounded_mask_size_bottom">0px</dimen> + + <!-- Rear Display Education dimens --> + <dimen name="rear_display_animation_width">273dp</dimen> + <dimen name="rear_display_animation_height">200dp</dimen> + <dimen name="rear_display_title_top_padding">24dp</dimen> + <dimen name="rear_display_title_bottom_padding">16dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 4cf09ab46684..2e5e11c03a65 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2847,4 +2847,17 @@ shortcut button on the lock screen. [CHAR LIMIT=NONE]. --> <string name="keyguard_affordance_enablement_dialog_home_instruction_2">• At least one device is available</string> + + <!-- Text for education page of cancel button to hide the page. [CHAR_LIMIT=NONE] --> + <string name="rear_display_bottom_sheet_cancel">Cancel</string> + <!-- Text for the user to confirm they flipped the device around. [CHAR_LIMIT=NONE] --> + <string name="rear_display_bottom_sheet_confirm">Flip now</string> + <!-- Text for education page title to guide user to unfold phone. [CHAR_LIMIT=50] --> + <string name="rear_display_fold_bottom_sheet_title">Unfold phone for a better selfie</string> + <!-- Text for education page title to guide user to flip to the front display. [CHAR_LIMIT=50] --> + <string name="rear_display_unfold_bottom_sheet_title">Flip to front display for a better selfie?</string> + <!-- Text for education page description to suggest user to use rear selfie capture. [CHAR_LIMIT=NONE] --> + <string name="rear_display_bottom_sheet_description">Use the rear-facing camera for a wider photo with higher resolution.</string> + <!-- Text for education page description to warn user that the display will turn off if the button is clicked. [CHAR_LIMIT=NONE] --> + <string name="rear_display_bottom_sheet_warning"><b>✱ This screen will turn off</b></string> </resources> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index fe4f639c307e..0c91ced7ab4d 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -314,6 +314,10 @@ <!-- Needed for MediaRoute chooser dialog --> <item name="*android:isLightTheme">false</item> + + <!-- Biometrics enroll color style --> + <item name="biometricsEnrollStyle">@style/BiometricsEnrollStyle</item> + </style> <style name="Theme.SystemUI.LightWallpaper"> @@ -1281,7 +1285,6 @@ <item name="android:textSize">@dimen/broadcast_dialog_btn_text_size</item> </style> - <!-- The style for log access consent dialog --> <style name="LogAccessDialogTheme" parent="@style/Theme.SystemUI.Dialog.Alert"> <item name="permissionGrantButtonTopStyle">@style/PermissionGrantButtonTop</item> @@ -1321,4 +1324,13 @@ <item name="android:layout_marginBottom">2dp</item> <item name="android:background">@drawable/grant_permissions_buttons_bottom</item> </style> + + <style name="BiometricsEnrollStyle"> + <item name="biometricsEnrollIcon">@color/udfps_enroll_icon</item> + <item name="biometricsMovingTargetFill">@color/udfps_moving_target_fill</item> + <item name="biometricsMovingTargetFillError">@color/udfps_moving_target_fill_error</item> + <item name="biometricsEnrollProgress">@color/udfps_enroll_progress</item> + <item name="biometricsEnrollProgressHelp">@color/udfps_enroll_progress_help</item> + <item name="biometricsEnrollProgressHelpWithTalkback">@color/udfps_enroll_progress_help_with_talkback</item> + </style> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt index b2a2a679b383..b962cc43eddf 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt @@ -107,6 +107,8 @@ open class AuthBiometricFingerprintIconController( if (shouldAnimateForTransition(lastState, newState)) { iconView.playAnimation() iconViewOverlay.playAnimation() + } else if (lastState == STATE_IDLE && newState == STATE_AUTHENTICATING_ANIMATING_IN) { + iconView.playAnimation() } LottieColorUtils.applyDynamicColors(context, iconView) LottieColorUtils.applyDynamicColors(context, iconViewOverlay) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java index 1e359584ceec..3e1c4e543779 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java @@ -20,6 +20,7 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.content.Context; +import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PointF; @@ -28,6 +29,7 @@ import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; +import android.util.AttributeSet; import android.view.animation.AccelerateDecelerateInterpolator; import androidx.annotation.NonNull; @@ -68,25 +70,29 @@ public class UdfpsEnrollDrawable extends UdfpsDrawable { private boolean mShouldShowTipHint = false; private boolean mShouldShowEdgeHint = false; - UdfpsEnrollDrawable(@NonNull Context context) { + private int mEnrollIcon; + private int mMovingTargetFill; + + UdfpsEnrollDrawable(@NonNull Context context, @Nullable AttributeSet attrs) { super(context); + loadResources(context, attrs); mSensorOutlinePaint = new Paint(0 /* flags */); mSensorOutlinePaint.setAntiAlias(true); - mSensorOutlinePaint.setColor(context.getColor(R.color.udfps_moving_target_fill)); + mSensorOutlinePaint.setColor(mMovingTargetFill); mSensorOutlinePaint.setStyle(Paint.Style.FILL); mBlueFill = new Paint(0 /* flags */); mBlueFill.setAntiAlias(true); - mBlueFill.setColor(context.getColor(R.color.udfps_moving_target_fill)); + mBlueFill.setColor(mMovingTargetFill); mBlueFill.setStyle(Paint.Style.FILL); mMovingTargetFpIcon = context.getResources() .getDrawable(R.drawable.ic_kg_fingerprint, null); - mMovingTargetFpIcon.setTint(context.getColor(R.color.udfps_enroll_icon)); + mMovingTargetFpIcon.setTint(mEnrollIcon); mMovingTargetFpIcon.mutate(); - getFingerprintDrawable().setTint(context.getColor(R.color.udfps_enroll_icon)); + getFingerprintDrawable().setTint(mEnrollIcon); mTargetAnimListener = new Animator.AnimatorListener() { @Override @@ -105,6 +111,16 @@ public class UdfpsEnrollDrawable extends UdfpsDrawable { }; } + void loadResources(Context context, @Nullable AttributeSet attrs) { + final TypedArray ta = context.obtainStyledAttributes(attrs, + R.styleable.BiometricsEnrollView, R.attr.biometricsEnrollStyle, + R.style.BiometricsEnrollStyle); + mEnrollIcon = ta.getColor(R.styleable.BiometricsEnrollView_biometricsEnrollIcon, 0); + mMovingTargetFill = ta.getColor( + R.styleable.BiometricsEnrollView_biometricsMovingTargetFill, 0); + ta.recycle(); + } + void setEnrollHelper(@NonNull UdfpsEnrollHelper helper) { mEnrollHelper = helper; } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java index af7e0b6244df..66a84245c16c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java @@ -18,6 +18,7 @@ package com.android.systemui.biometrics; import android.animation.ValueAnimator; import android.content.Context; +import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; @@ -26,6 +27,7 @@ import android.os.Process; import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; +import android.util.AttributeSet; import android.view.accessibility.AccessibilityManager; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; @@ -93,17 +95,25 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable { @Nullable private ValueAnimator mCheckmarkAnimator; @NonNull private final ValueAnimator.AnimatorUpdateListener mCheckmarkUpdateListener; - public UdfpsEnrollProgressBarDrawable(@NonNull Context context) { + private int mMovingTargetFill; + private int mMovingTargetFillError; + private int mEnrollProgress; + private int mEnrollProgressHelp; + private int mEnrollProgressHelpWithTalkback; + + public UdfpsEnrollProgressBarDrawable(@NonNull Context context, @Nullable AttributeSet attrs) { mContext = context; + + loadResources(context, attrs); mStrokeWidthPx = Utils.dpToPixels(context, STROKE_WIDTH_DP); - mProgressColor = context.getColor(R.color.udfps_enroll_progress); + mProgressColor = mEnrollProgress; final AccessibilityManager am = context.getSystemService(AccessibilityManager.class); mIsAccessibilityEnabled = am.isTouchExplorationEnabled(); - mOnFirstBucketFailedColor = context.getColor(R.color.udfps_moving_target_fill_error); + mOnFirstBucketFailedColor = mMovingTargetFillError; if (!mIsAccessibilityEnabled) { - mHelpColor = context.getColor(R.color.udfps_enroll_progress_help); + mHelpColor = mEnrollProgressHelp; } else { - mHelpColor = context.getColor(R.color.udfps_enroll_progress_help_with_talkback); + mHelpColor = mEnrollProgressHelpWithTalkback; } mCheckmarkDrawable = context.getDrawable(R.drawable.udfps_enroll_checkmark); mCheckmarkDrawable.mutate(); @@ -111,7 +121,7 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable { mBackgroundPaint = new Paint(); mBackgroundPaint.setStrokeWidth(mStrokeWidthPx); - mBackgroundPaint.setColor(context.getColor(R.color.udfps_moving_target_fill)); + mBackgroundPaint.setColor(mMovingTargetFill); mBackgroundPaint.setAntiAlias(true); mBackgroundPaint.setStyle(Paint.Style.STROKE); mBackgroundPaint.setStrokeCap(Paint.Cap.ROUND); @@ -147,6 +157,23 @@ public class UdfpsEnrollProgressBarDrawable extends Drawable { }; } + void loadResources(Context context, @Nullable AttributeSet attrs) { + final TypedArray ta = context.obtainStyledAttributes(attrs, + R.styleable.BiometricsEnrollView, R.attr.biometricsEnrollStyle, + R.style.BiometricsEnrollStyle); + mMovingTargetFill = ta.getColor( + R.styleable.BiometricsEnrollView_biometricsMovingTargetFill, 0); + mMovingTargetFillError = ta.getColor( + R.styleable.BiometricsEnrollView_biometricsMovingTargetFillError, 0); + mEnrollProgress = ta.getColor( + R.styleable.BiometricsEnrollView_biometricsEnrollProgress, 0); + mEnrollProgressHelp = ta.getColor( + R.styleable.BiometricsEnrollView_biometricsEnrollProgressHelp, 0); + mEnrollProgressHelpWithTalkback = ta.getColor( + R.styleable.BiometricsEnrollView_biometricsEnrollProgressHelpWithTalkback, 0); + ta.recycle(); + } + void onEnrollmentProgress(int remaining, int totalSteps) { mAfterFirstTouch = true; updateState(remaining, totalSteps, false /* showingHelp */); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java index 87be42c3426e..1cc414150835 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java @@ -47,8 +47,8 @@ public class UdfpsEnrollView extends UdfpsAnimationView { public UdfpsEnrollView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); - mFingerprintDrawable = new UdfpsEnrollDrawable(mContext); - mFingerprintProgressDrawable = new UdfpsEnrollProgressBarDrawable(context); + mFingerprintDrawable = new UdfpsEnrollDrawable(mContext, attrs); + mFingerprintProgressDrawable = new UdfpsEnrollProgressBarDrawable(context, attrs); mHandler = new Handler(Looper.getMainLooper()); } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt index 4dfcd6398a4d..66e5d7c4a3bc 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt @@ -30,6 +30,7 @@ import android.os.UserHandle import android.service.controls.ControlsProviderService import androidx.annotation.WorkerThread import com.android.settingslib.applications.DefaultAppInfo +import com.android.systemui.R import java.util.Objects class ControlsServiceInfo( @@ -59,7 +60,8 @@ class ControlsServiceInfo( * instead of using the controls rendered by SystemUI. * * The activity must be in the same package, exported, enabled and protected by the - * [Manifest.permission.BIND_CONTROLS] permission. + * [Manifest.permission.BIND_CONTROLS] permission. Additionally, only packages declared in + * [R.array.config_controlsPreferredPackages] can declare activities for use as a panel. */ var panelActivity: ComponentName? = null private set @@ -70,6 +72,9 @@ class ControlsServiceInfo( fun resolvePanelActivity() { if (resolved) return resolved = true + val validPackages = context.resources + .getStringArray(R.array.config_controlsPreferredPackages) + if (componentName.packageName !in validPackages) return panelActivity = _panelActivity?.let { val resolveInfos = mPm.queryIntentActivitiesAsUser( Intent().setComponent(it), diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index 09743ef7aebf..85ba68c9a753 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -37,6 +37,7 @@ import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver import com.android.systemui.media.taptotransfer.sender.MediaTttSenderCoordinator import com.android.systemui.power.PowerUI +import com.android.systemui.reardisplay.RearDisplayDialogController import com.android.systemui.recents.Recents import com.android.systemui.settings.dagger.MultiUserUtilsModule import com.android.systemui.shortcut.ShortcutKeyDispatcher @@ -250,4 +251,11 @@ abstract class SystemUICoreStartableModule { @IntoMap @ClassKey(ChipbarCoordinator::class) abstract fun bindChipbarController(sysui: ChipbarCoordinator): CoreStartable + + + /** Inject into RearDisplayDialogController) */ + @Binds + @IntoMap + @ClassKey(RearDisplayDialogController::class) + abstract fun bindRearDisplayDialogController(sysui: RearDisplayDialogController): CoreStartable } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index e2f86bd76216..aa6c619d9969 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -366,6 +366,11 @@ object Flags { @JvmField val NEW_BACK_AFFORDANCE = unreleasedFlag(1203, "new_back_affordance", teamfood = false) + // TODO(b/255854141): Tracking Bug + @JvmField + val WM_ENABLE_PREDICTIVE_BACK_SYSUI = + unreleasedFlag(1204, "persist.wm.debug.predictive_back_sysui_enable", teamfood = false) + // 1300 - screenshots // TODO(b/254512719): Tracking Bug @JvmField val SCREENSHOT_REQUEST_PROCESSOR = releasedFlag(1300, "screenshot_request_processor") @@ -386,7 +391,7 @@ object Flags { // 1600 - accessibility @JvmField val A11Y_FLOATING_MENU_FLING_SPRING_ANIMATIONS = - unreleasedFlag(1600, "a11y_floating_menu_fling_spring_animations") + unreleasedFlag(1600, "a11y_floating_menu_fling_spring_animations", teamfood = true) // 1700 - clipboard @JvmField val CLIPBOARD_OVERLAY_REFACTOR = releasedFlag(1700, "clipboard_overlay_refactor") diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt index f5220b8fae92..73dbeab3030b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt @@ -25,6 +25,7 @@ package com.android.systemui.keyguard.data.quickaffordance object BuiltInKeyguardQuickAffordanceKeys { // Please keep alphabetical order of const names to simplify future maintenance. const val CAMERA = "camera" + const val FLASHLIGHT = "flashlight" const val HOME_CONTROLS = "home" const val QR_CODE_SCANNER = "qr_code_scanner" const val QUICK_ACCESS_WALLET = "wallet" diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt new file mode 100644 index 000000000000..49527d32d229 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.keyguard.data.quickaffordance + +import android.content.Context +import com.android.systemui.R +import com.android.systemui.animation.Expandable +import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow +import com.android.systemui.common.shared.model.ContentDescription +import com.android.systemui.common.shared.model.Icon +import com.android.systemui.keyguard.shared.quickaffordance.ActivationState +import com.android.systemui.statusbar.policy.FlashlightController +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +@SysUISingleton +class FlashlightQuickAffordanceConfig @Inject constructor( + @Application private val context: Context, + private val flashlightController: FlashlightController, +) : KeyguardQuickAffordanceConfig { + + private sealed class FlashlightState { + + abstract fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState + + object On: FlashlightState() { + override fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState = + KeyguardQuickAffordanceConfig.LockScreenState.Visible( + Icon.Resource( + R.drawable.ic_flashlight_on, + ContentDescription.Resource(R.string.quick_settings_flashlight_label) + ), + ActivationState.Active + ) + } + + object OffAvailable: FlashlightState() { + override fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState = + KeyguardQuickAffordanceConfig.LockScreenState.Visible( + Icon.Resource( + R.drawable.ic_flashlight_off, + ContentDescription.Resource(R.string.quick_settings_flashlight_label) + ), + ActivationState.Inactive + ) + } + + object Unavailable: FlashlightState() { + override fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState = + KeyguardQuickAffordanceConfig.LockScreenState.Hidden + } + } + + override val key: String + get() = BuiltInKeyguardQuickAffordanceKeys.FLASHLIGHT + + override val pickerName: String + get() = context.getString(R.string.quick_settings_flashlight_label) + + override val pickerIconResourceId: Int + get() = if (flashlightController.isEnabled) { + R.drawable.ic_flashlight_on + } else { + R.drawable.ic_flashlight_off + } + + override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> = + conflatedCallbackFlow { + val flashlightCallback = object : FlashlightController.FlashlightListener { + override fun onFlashlightChanged(enabled: Boolean) { + trySendWithFailureLogging( + if (enabled) { + FlashlightState.On.toLockScreenState() + } else { + FlashlightState.OffAvailable.toLockScreenState() + }, + TAG + ) + } + + override fun onFlashlightError() { + trySendWithFailureLogging(FlashlightState.OffAvailable.toLockScreenState(), TAG) + } + + override fun onFlashlightAvailabilityChanged(available: Boolean) { + trySendWithFailureLogging( + if (!available) { + FlashlightState.Unavailable.toLockScreenState() + } else { + if (flashlightController.isEnabled) { + FlashlightState.On.toLockScreenState() + } else { + FlashlightState.OffAvailable.toLockScreenState() + } + }, + TAG + ) + } + } + + flashlightController.addCallback(flashlightCallback) + + awaitClose { + flashlightController.removeCallback(flashlightCallback) + } + } + + override fun onTriggered(expandable: Expandable?): + KeyguardQuickAffordanceConfig.OnTriggeredResult { + flashlightController + .setFlashlight(flashlightController.isAvailable && !flashlightController.isEnabled) + return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled + } + + override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState = + if (flashlightController.isAvailable) { + KeyguardQuickAffordanceConfig.PickerScreenState.Default + } else { + KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice + } + + companion object { + private const val TAG = "FlashlightQuickAffordanceConfig" + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt index f7225a249eda..3013227c21c0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt @@ -26,6 +26,7 @@ object KeyguardDataQuickAffordanceModule { @Provides @ElementsIntoSet fun quickAffordanceConfigs( + flashlight: FlashlightQuickAffordanceConfig, home: HomeControlsKeyguardQuickAffordanceConfig, quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig, qrCodeScanner: QrCodeScannerKeyguardQuickAffordanceConfig, @@ -33,6 +34,7 @@ object KeyguardDataQuickAffordanceModule { ): Set<KeyguardQuickAffordanceConfig> { return setOf( camera, + flashlight, home, quickAccessWallet, qrCodeScanner, diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt index f9e341c8629a..d6e29e0f2067 100644 --- a/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt @@ -16,9 +16,9 @@ package com.android.systemui.log -import android.app.ActivityManager import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager +import com.android.systemui.log.LogBufferHelper.Companion.adjustMaxSize import com.android.systemui.plugins.log.LogBuffer import com.android.systemui.plugins.log.LogcatEchoTracker @@ -29,15 +29,6 @@ class LogBufferFactory @Inject constructor( private val dumpManager: DumpManager, private val logcatEchoTracker: LogcatEchoTracker ) { - /* limitiometricMessageDeferralLogger the size of maxPoolSize for low ram (Go) devices */ - private fun adjustMaxSize(requestedMaxSize: Int): Int { - return if (ActivityManager.isLowRamDeviceStatic()) { - minOf(requestedMaxSize, 20) /* low ram max log size*/ - } else { - requestedMaxSize - } - } - @JvmOverloads fun create( name: String, diff --git a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java b/packages/SystemUI/src/com/android/systemui/log/LogBufferHelper.kt index 188dff21efa4..619eac1dbdc3 100644 --- a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java +++ b/packages/SystemUI/src/com/android/systemui/log/LogBufferHelper.kt @@ -14,22 +14,19 @@ * limitations under the License. */ -package com.android.systemui.robotests; +package com.android.systemui.log -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; -import static com.google.common.truth.Truth.assertThat; -import org.junit.Test; -import org.junit.runner.RunWith; +import android.app.ActivityManager -@SmallTest -@RunWith(AndroidJUnit4.class) -public class SysuiResourceLoadingTest extends SysuiRoboBase { - @Test - public void testResources() { - assertThat(getContext().getString(com.android.systemui.R.string.app_label)) - .isEqualTo("System UI"); - assertThat(getContext().getString(com.android.systemui.tests.R.string.test_content)) - .isNotEmpty(); +class LogBufferHelper { + companion object { + /** If necessary, returns a limited maximum size for low ram (Go) devices */ + fun adjustMaxSize(requestedMaxSize: Int): Int { + return if (ActivityManager.isLowRamDeviceStatic()) { + minOf(requestedMaxSize, 20) /* low ram max log size*/ + } else { + requestedMaxSize + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt new file mode 100644 index 000000000000..c27bfa338df3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.table + +import com.android.systemui.util.kotlin.pairwiseBy +import kotlinx.coroutines.flow.Flow + +/** + * An interface that enables logging the difference between values in table format. + * + * Many objects that we want to log are data-y objects with a collection of fields. When logging + * these objects, we want to log each field separately. This allows ABT (Android Bug Tool) to easily + * highlight changes in individual fields. + * + * See [TableLogBuffer]. + */ +interface Diffable<T> { + /** + * Finds the differences between [prevVal] and [this] and logs those diffs to [row]. + * + * Each implementer should determine which individual fields have changed between [prevVal] and + * [this], and only log the fields that have actually changed. This helps save buffer space. + * + * For example, if: + * - prevVal = Object(val1=100, val2=200, val3=300) + * - this = Object(val1=100, val2=200, val3=333) + * + * Then only the val3 change should be logged. + */ + fun logDiffs(prevVal: T, row: TableRowLogger) +} + +/** + * Each time the flow is updated with a new value, logs the differences between the previous value + * and the new value to the given [tableLogBuffer]. + * + * The new value's [Diffable.logDiffs] method will be used to log the differences to the table. + * + * @param columnPrefix a prefix that will be applied to every column name that gets logged. + */ +fun <T : Diffable<T>> Flow<T>.logDiffsForTable( + tableLogBuffer: TableLogBuffer, + columnPrefix: String, + initialValue: T, +): Flow<T> { + return this.pairwiseBy(initialValue) { prevVal, newVal -> + tableLogBuffer.logDiffs(columnPrefix, prevVal, newVal) + newVal + } +} diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt new file mode 100644 index 000000000000..68c297f76ab7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.table + +/** + * A object used with [TableLogBuffer] to store changes in variables over time. Is recyclable. + * + * Each message represents a change to exactly 1 type, specified by [DataType]. + */ +data class TableChange( + var timestamp: Long = 0, + var columnPrefix: String = "", + var columnName: String = "", + var type: DataType = DataType.EMPTY, + var bool: Boolean = false, + var int: Int = 0, + var str: String? = null, +) { + /** Resets to default values so that the object can be recycled. */ + fun reset(timestamp: Long, columnPrefix: String, columnName: String) { + this.timestamp = timestamp + this.columnPrefix = columnPrefix + this.columnName = columnName + this.type = DataType.EMPTY + this.bool = false + this.int = 0 + this.str = null + } + + /** Sets this to store a string change. */ + fun set(value: String?) { + type = DataType.STRING + str = value + } + + /** Sets this to store a boolean change. */ + fun set(value: Boolean) { + type = DataType.BOOLEAN + bool = value + } + + /** Sets this to store an int change. */ + fun set(value: Int) { + type = DataType.INT + int = value + } + + /** Returns true if this object has a change. */ + fun hasData(): Boolean { + return columnName.isNotBlank() && type != DataType.EMPTY + } + + fun getName(): String { + return if (columnPrefix.isNotBlank()) { + "$columnPrefix.$columnName" + } else { + columnName + } + } + + fun getVal(): String { + return when (type) { + DataType.EMPTY -> null + DataType.STRING -> str + DataType.INT -> int + DataType.BOOLEAN -> bool + }.toString() + } + + enum class DataType { + STRING, + BOOLEAN, + INT, + EMPTY, + } +} diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt new file mode 100644 index 000000000000..429637a0ee4d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.table + +import androidx.annotation.VisibleForTesting +import com.android.systemui.Dumpable +import com.android.systemui.dump.DumpManager +import com.android.systemui.dump.DumpsysTableLogger +import com.android.systemui.plugins.util.RingBuffer +import com.android.systemui.util.time.SystemClock +import java.io.PrintWriter +import java.text.SimpleDateFormat +import java.util.Locale +import kotlinx.coroutines.flow.Flow + +/** + * A logger that logs changes in table format. + * + * Some parts of System UI maintain a lot of pieces of state at once. + * [com.android.systemui.plugins.log.LogBuffer] allows us to easily log change events: + * + * - 10-10 10:10:10.456: state2 updated to newVal2 + * - 10-10 10:11:00.000: stateN updated to StateN(val1=true, val2=1) + * - 10-10 10:11:02.123: stateN updated to StateN(val1=true, val2=2) + * - 10-10 10:11:05.123: state1 updated to newVal1 + * - 10-10 10:11:06.000: stateN updated to StateN(val1=false, val2=3) + * + * However, it can sometimes be more useful to view the state changes in table format: + * + * - timestamp--------- | state1- | state2- | ... | stateN.val1 | stateN.val2 + * - ------------------------------------------------------------------------- + * - 10-10 10:10:10.123 | val1--- | val2--- | ... | false------ | 0----------- + * - 10-10 10:10:10.456 | val1--- | newVal2 | ... | false------ | 0----------- + * - 10-10 10:11:00.000 | val1--- | newVal2 | ... | true------- | 1----------- + * - 10-10 10:11:02.123 | val1--- | newVal2 | ... | true------- | 2----------- + * - 10-10 10:11:05.123 | newVal1 | newVal2 | ... | true------- | 2----------- + * - 10-10 10:11:06.000 | newVal1 | newVal2 | ... | false------ | 3----------- + * + * This class enables easy logging of the state changes in both change event format and table + * format. + * + * This class also enables easy logging of states that are a collection of fields. For example, + * stateN in the above example consists of two fields -- val1 and val2. It's useful to put each + * field into its own column so that ABT (Android Bug Tool) can easily highlight changes to + * individual fields. + * + * How it works: + * + * 1) Create an instance of this buffer via [TableLogBufferFactory]. + * + * 2) For any states being logged, implement [Diffable]. Implementing [Diffable] allows the state to + * only log the fields that have *changed* since the previous update, instead of always logging all + * fields. + * + * 3) Each time a change in a state happens, call [logDiffs]. If your state is emitted using a + * [Flow], you should use the [logDiffsForTable] extension function to automatically log diffs any + * time your flow emits a new value. + * + * When a dump occurs, there will be two dumps: + * + * 1) The change events under the dumpable name "$name-changes". + * + * 2) This class will coalesce all the diffs into a table format and log them under the dumpable + * name "$name-table". + * + * @param maxSize the maximum size of the buffer. Must be > 0. + */ +class TableLogBuffer( + maxSize: Int, + private val name: String, + private val systemClock: SystemClock, +) { + init { + if (maxSize <= 0) { + throw IllegalArgumentException("maxSize must be > 0") + } + } + + private val buffer = RingBuffer(maxSize) { TableChange() } + + // A [TableRowLogger] object, re-used each time [logDiffs] is called. + // (Re-used to avoid object allocation.) + private val tempRow = TableRowLoggerImpl(0, columnPrefix = "", this) + + /** + * Log the differences between [prevVal] and [newVal]. + * + * The [newVal] object's method [Diffable.logDiffs] will be used to fetch the diffs. + * + * @param columnPrefix a prefix that will be applied to every column name that gets logged. This + * ensures that all the columns related to the same state object will be grouped together in the + * table. + */ + @Synchronized + fun <T : Diffable<T>> logDiffs(columnPrefix: String, prevVal: T, newVal: T) { + val row = tempRow + row.timestamp = systemClock.currentTimeMillis() + row.columnPrefix = columnPrefix + newVal.logDiffs(prevVal, row) + } + + // Keep these individual [logChange] methods private (don't let clients give us their own + // timestamps.) + + private fun logChange(timestamp: Long, prefix: String, columnName: String, value: String?) { + val change = obtain(timestamp, prefix, columnName) + change.set(value) + } + + private fun logChange(timestamp: Long, prefix: String, columnName: String, value: Boolean) { + val change = obtain(timestamp, prefix, columnName) + change.set(value) + } + + private fun logChange(timestamp: Long, prefix: String, columnName: String, value: Int) { + val change = obtain(timestamp, prefix, columnName) + change.set(value) + } + + // TODO(b/259454430): Add additional change types here. + + @Synchronized + private fun obtain(timestamp: Long, prefix: String, columnName: String): TableChange { + val tableChange = buffer.advance() + tableChange.reset(timestamp, prefix, columnName) + return tableChange + } + + /** + * Registers this buffer as dumpables in [dumpManager]. Must be called for the table to be + * dumped. + * + * This will be automatically called in [TableLogBufferFactory.create]. + */ + fun registerDumpables(dumpManager: DumpManager) { + dumpManager.registerNormalDumpable("$name-changes", changeDumpable) + dumpManager.registerNormalDumpable("$name-table", tableDumpable) + } + + private val changeDumpable = Dumpable { pw, _ -> dumpChanges(pw) } + private val tableDumpable = Dumpable { pw, _ -> dumpTable(pw) } + + /** Dumps the list of [TableChange] objects. */ + @Synchronized + @VisibleForTesting + fun dumpChanges(pw: PrintWriter) { + for (i in 0 until buffer.size) { + buffer[i].dump(pw) + } + } + + /** Dumps an individual [TableChange]. */ + private fun TableChange.dump(pw: PrintWriter) { + if (!this.hasData()) { + return + } + val formattedTimestamp = TABLE_LOG_DATE_FORMAT.format(timestamp) + pw.print(formattedTimestamp) + pw.print(" ") + pw.print(this.getName()) + pw.print("=") + pw.print(this.getVal()) + pw.println() + } + + /** + * Coalesces all the [TableChange] objects into a table of values of time and dumps the table. + */ + // TODO(b/259454430): Since this is an expensive process, it could cause the bug report dump to + // fail and/or not dump anything else. We should move this processing to ABT (Android Bug + // Tool), where we have unlimited time to process. + @Synchronized + @VisibleForTesting + fun dumpTable(pw: PrintWriter) { + val messages = buffer.iterator().asSequence().toList() + + if (messages.isEmpty()) { + return + } + + // Step 1: Create list of column headers + val headerSet = mutableSetOf<String>() + messages.forEach { headerSet.add(it.getName()) } + val headers: MutableList<String> = headerSet.toList().sorted().toMutableList() + headers.add(0, "timestamp") + + // Step 2: Create a list with the current values for each column. Will be updated with each + // change. + val currentRow: MutableList<String> = MutableList(headers.size) { DEFAULT_COLUMN_VALUE } + + // Step 3: For each message, make the correct update to [currentRow] and save it to [rows]. + val columnIndices: Map<String, Int> = + headers.mapIndexed { index, headerName -> headerName to index }.toMap() + val allRows = mutableListOf<List<String>>() + + messages.forEach { + if (!it.hasData()) { + return@forEach + } + + val formattedTimestamp = TABLE_LOG_DATE_FORMAT.format(it.timestamp) + if (formattedTimestamp != currentRow[0]) { + // The timestamp has updated, so save the previous row and continue to the next row + allRows.add(currentRow.toList()) + currentRow[0] = formattedTimestamp + } + val columnIndex = columnIndices[it.getName()]!! + currentRow[columnIndex] = it.getVal() + } + // Add the last row + allRows.add(currentRow.toList()) + + // Step 4: Dump the rows + DumpsysTableLogger( + name, + headers, + allRows, + ) + .printTableData(pw) + } + + /** + * A private implementation of [TableRowLogger]. + * + * Used so that external clients can't modify [timestamp]. + */ + private class TableRowLoggerImpl( + var timestamp: Long, + var columnPrefix: String, + val tableLogBuffer: TableLogBuffer, + ) : TableRowLogger { + /** Logs a change to a string value. */ + override fun logChange(columnName: String, value: String?) { + tableLogBuffer.logChange(timestamp, columnPrefix, columnName, value) + } + + /** Logs a change to a boolean value. */ + override fun logChange(columnName: String, value: Boolean) { + tableLogBuffer.logChange(timestamp, columnPrefix, columnName, value) + } + + /** Logs a change to an int value. */ + override fun logChange(columnName: String, value: Int) { + tableLogBuffer.logChange(timestamp, columnPrefix, columnName, value) + } + } +} + +val TABLE_LOG_DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US) +private const val DEFAULT_COLUMN_VALUE = "UNKNOWN" diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt new file mode 100644 index 000000000000..f1f906f46d2d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.table + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dump.DumpManager +import com.android.systemui.log.LogBufferHelper.Companion.adjustMaxSize +import com.android.systemui.util.time.SystemClock +import javax.inject.Inject + +@SysUISingleton +class TableLogBufferFactory +@Inject +constructor( + private val dumpManager: DumpManager, + private val systemClock: SystemClock, +) { + fun create( + name: String, + maxSize: Int, + ): TableLogBuffer { + val tableBuffer = TableLogBuffer(adjustMaxSize(maxSize), name, systemClock) + tableBuffer.registerDumpables(dumpManager) + return tableBuffer + } +} diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableRowLogger.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableRowLogger.kt new file mode 100644 index 000000000000..a7ba13b55ed8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/table/TableRowLogger.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.table + +/** + * A class that logs a row to [TableLogBuffer]. + * + * Objects that implement [Diffable] will receive an instance of this class, and can log any changes + * to individual fields using the [logChange] methods. All logged changes will be associated with + * the same timestamp. + */ +interface TableRowLogger { + /** Logs a change to a string value. */ + fun logChange(columnName: String, value: String?) + + /** Logs a change to a boolean value. */ + fun logChange(columnName: String, value: Boolean) + + /** Logs a change to an int value. */ + fun logChange(columnName: String, value: Int) +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java index 22f91f359de8..bfa67a89baca 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java @@ -109,7 +109,6 @@ public class MediaProjectionPermissionActivity extends Activity CharSequence dialogTitle = null; String appName = null; if (Utils.isHeadlessRemoteDisplayProvider(packageManager, mPackageName)) { - // TODO(b/253438807): handle special app name dialogText = getString(R.string.media_projection_dialog_service_text); dialogTitle = getString(R.string.media_projection_dialog_service_title); } else { diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt index cbb670ebf02d..b252be1b4cdc 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt @@ -799,6 +799,16 @@ constructor( } if ( + desiredLocation == LOCATION_QS && + previousLocation == LOCATION_LOCKSCREEN && + statusbarState == StatusBarState.SHADE + ) { + // This is an invalid transition, can happen when tapping on home control and the UMO + // while being on landscape orientation in tablet. + return false + } + + if ( statusbarState == StatusBarState.KEYGUARD && (currentLocation == LOCATION_LOCKSCREEN || previousLocation == LOCATION_LOCKSCREEN) ) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index 33021e3cde47..2c0745bf0f0d 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -16,6 +16,8 @@ package com.android.systemui.navigationbar; +import static android.app.StatusBarManager.WINDOW_NAVIGATION_BAR; +import static android.app.StatusBarManager.WindowVisibleState; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS; @@ -58,6 +60,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.system.QuickStepContract; +import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -86,7 +89,7 @@ public final class NavBarHelper implements AccessibilityButtonModeObserver.ModeChangedListener, AccessibilityButtonTargetsObserver.TargetsChangedListener, OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener, - Dumpable { + Dumpable, CommandQueue.Callbacks { private final AccessibilityManager mAccessibilityManager; private final Lazy<AssistManager> mAssistManagerLazy; private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy; @@ -97,13 +100,18 @@ public final class NavBarHelper implements private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver; private final List<NavbarTaskbarStateUpdater> mA11yEventListeners = new ArrayList<>(); private final Context mContext; - private ContentResolver mContentResolver; + private final CommandQueue mCommandQueue; + private final ContentResolver mContentResolver; private boolean mAssistantAvailable; private boolean mLongPressHomeEnabled; private boolean mAssistantTouchGestureEnabled; private int mNavBarMode; private int mA11yButtonState; + // Attributes used in NavBarHelper.CurrentSysuiState + private int mWindowStateDisplayId; + private @WindowVisibleState int mWindowState; + private final ContentObserver mAssistContentObserver = new ContentObserver( new Handler(Looper.getMainLooper())) { @Override @@ -128,8 +136,10 @@ public final class NavBarHelper implements KeyguardStateController keyguardStateController, NavigationModeController navigationModeController, UserTracker userTracker, - DumpManager dumpManager) { + DumpManager dumpManager, + CommandQueue commandQueue) { mContext = context; + mCommandQueue = commandQueue; mContentResolver = mContext.getContentResolver(); mAccessibilityManager = accessibilityManager; mAssistManagerLazy = assistManagerLazy; @@ -160,10 +170,13 @@ public final class NavBarHelper implements false, mAssistContentObserver, UserHandle.USER_ALL); updateAssistantAvailability(); updateA11yState(); + mCommandQueue.addCallback(this); + } public void destroy() { mContentResolver.unregisterContentObserver(mAssistContentObserver); + mCommandQueue.removeCallback(this); } /** @@ -333,6 +346,20 @@ public final class NavBarHelper implements || (!isKeyguardShowing && (vis & InputMethodService.IME_VISIBLE) != 0); } + @Override + public void setWindowState(int displayId, int window, int state) { + CommandQueue.Callbacks.super.setWindowState(displayId, window, state); + if (window != WINDOW_NAVIGATION_BAR) { + return; + } + mWindowStateDisplayId = displayId; + mWindowState = state; + } + + public CurrentSysuiState getCurrentSysuiState() { + return new CurrentSysuiState(); + } + /** * Callbacks will get fired once immediately after registering via * {@link #registerNavTaskStateUpdater(NavbarTaskbarStateUpdater)} @@ -342,6 +369,17 @@ public final class NavBarHelper implements void updateAssistantAvailable(boolean available); } + /** Data class to help Taskbar/Navbar initiate state correctly when switching between the two.*/ + public class CurrentSysuiState { + public final int mWindowStateDisplayId; + public final @WindowVisibleState int mWindowState; + + public CurrentSysuiState() { + mWindowStateDisplayId = NavBarHelper.this.mWindowStateDisplayId; + mWindowState = NavBarHelper.this.mWindowState; + } + } + static @TransitionMode int transitionMode(boolean isTransient, int appearance) { final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS; if (isTransient) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index b9f5859e80eb..d132a95dedcb 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -666,6 +666,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mDisplayId = mContext.getDisplayId(); mIsOnDefaultDisplay = mDisplayId == DEFAULT_DISPLAY; + // Ensure we try to get currentSysuiState from navBarHelper before command queue callbacks + // start firing, since the latter is source of truth + parseCurrentSysuiState(); mCommandQueue.addCallback(this); mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled(); mNavBarHelper.init(); @@ -952,6 +955,13 @@ public class NavigationBar extends ViewController<NavigationBarView> implements setOrientedHandleSamplingRegion(null); } + private void parseCurrentSysuiState() { + NavBarHelper.CurrentSysuiState state = mNavBarHelper.getCurrentSysuiState(); + if (state.mWindowStateDisplayId == mDisplayId) { + mNavigationBarWindowState = state.mWindowState; + } + } + private void reconfigureHomeLongClick() { if (mView.getHomeButton().getCurrentView() == null) { return; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index eb87ff08d123..ac7c70bd1d9e 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -214,6 +214,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, return; } mDisplayId = displayId; + parseCurrentSysuiState(); mCommandQueue.addCallback(this); mOverviewProxyService.addCallback(this); mEdgeBackGestureHandler.onNavigationModeChanged( @@ -271,6 +272,13 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, return mInitialized; } + private void parseCurrentSysuiState() { + NavBarHelper.CurrentSysuiState state = mNavBarHelper.getCurrentSysuiState(); + if (state.mWindowStateDisplayId == mDisplayId) { + mTaskBarWindowState = state.mWindowState; + } + } + private void updateSysuiFlags() { int a11yFlags = mNavBarHelper.getA11yButtonState(); boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0; diff --git a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java new file mode 100644 index 000000000000..802db7e9d0c0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.reardisplay; + +import android.annotation.SuppressLint; +import android.annotation.TestApi; +import android.content.Context; +import android.hardware.devicestate.DeviceStateManager; +import android.hardware.devicestate.DeviceStateManagerGlobal; +import android.view.View; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.CoreStartable; +import com.android.systemui.R; +import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.phone.SystemUIDialog; + +import com.airbnb.lottie.LottieAnimationView; +import com.airbnb.lottie.LottieDrawable; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +/** + * Provides an educational dialog to the user alerting them to what + * they may need to do to enter rear display mode. This may be to open the + * device if it is currently folded, or to confirm that they would like + * the content to move to the screen on their device that is aligned with + * the rear camera. This includes a device animation to provide more context + * to the user. + * + * We are suppressing lint for the VisibleForTests check because the use of + * DeviceStateManagerGlobal as in this file should not be encouraged for other use-cases. + * The lint check will notify any other use-cases that they are possibly doing something + * incorrectly. + */ +@SuppressLint("VisibleForTests") // TODO(b/260264542) Migrate away from DeviceStateManagerGlobal +@SysUISingleton +public class RearDisplayDialogController implements CoreStartable, CommandQueue.Callbacks { + + private int[] mFoldedStates; + private boolean mStartedFolded; + private boolean mServiceNotified = false; + private int mAnimationRepeatCount = LottieDrawable.INFINITE; + + private DeviceStateManagerGlobal mDeviceStateManagerGlobal; + private DeviceStateManager.DeviceStateCallback mDeviceStateManagerCallback = + new DeviceStateManagerCallback(); + + private final Context mContext; + private final CommandQueue mCommandQueue; + private final Executor mExecutor; + + @VisibleForTesting + SystemUIDialog mRearDisplayEducationDialog; + + @Inject + public RearDisplayDialogController(Context context, CommandQueue commandQueue, + @Main Executor executor) { + mContext = context; + mCommandQueue = commandQueue; + mExecutor = executor; + } + + @Override + public void start() { + mCommandQueue.addCallback(this); + } + + @Override + public void showRearDisplayDialog(int currentBaseState) { + initializeValues(currentBaseState); + createAndShowDialog(); + } + + private void createAndShowDialog() { + mServiceNotified = false; + Context dialogContext = mRearDisplayEducationDialog.getContext(); + + View dialogView; + if (mStartedFolded) { + dialogView = View.inflate(dialogContext, + R.layout.activity_rear_display_education, null); + } else { + dialogView = View.inflate(dialogContext, + R.layout.activity_rear_display_education_opened, null); + } + LottieAnimationView animationView = dialogView.findViewById( + R.id.rear_display_folded_animation); + animationView.setRepeatCount(mAnimationRepeatCount); + mRearDisplayEducationDialog.setView(dialogView); + + configureDialogButtons(); + + mRearDisplayEducationDialog.show(); + } + + /** + * Configures the buttons on the dialog depending on the starting device posture + */ + private void configureDialogButtons() { + // If we are open, we need to provide a confirm option + if (!mStartedFolded) { + mRearDisplayEducationDialog.setPositiveButton( + R.string.rear_display_bottom_sheet_confirm, + (dialog, which) -> closeOverlayAndNotifyService(false), true); + } + mRearDisplayEducationDialog.setNegativeButton(R.string.rear_display_bottom_sheet_cancel, + (dialog, which) -> closeOverlayAndNotifyService(true), true); + mRearDisplayEducationDialog.setOnDismissListener(dialog -> { + // Dialog is being dismissed before we've notified the system server + if (!mServiceNotified) { + closeOverlayAndNotifyService(true); + } + }); + } + + /** + * Initializes properties and values we need when getting ready to show the dialog. + * + * Ensures we're not using old values from when the dialog may have been shown previously. + */ + private void initializeValues(int startingBaseState) { + mRearDisplayEducationDialog = new SystemUIDialog(mContext); + if (mFoldedStates == null) { + mFoldedStates = mContext.getResources().getIntArray( + com.android.internal.R.array.config_foldedDeviceStates); + } + mStartedFolded = isFoldedState(startingBaseState); + mDeviceStateManagerGlobal = DeviceStateManagerGlobal.getInstance(); + mDeviceStateManagerGlobal.registerDeviceStateCallback(mDeviceStateManagerCallback, + mExecutor); + } + + private boolean isFoldedState(int state) { + for (int i = 0; i < mFoldedStates.length; i++) { + if (mFoldedStates[i] == state) return true; + } + return false; + } + + /** + * Closes the educational overlay, and notifies the system service if rear display mode + * should be cancelled or enabled. + */ + private void closeOverlayAndNotifyService(boolean shouldCancelRequest) { + mServiceNotified = true; + mDeviceStateManagerGlobal.unregisterDeviceStateCallback(mDeviceStateManagerCallback); + mDeviceStateManagerGlobal.onStateRequestOverlayDismissed(shouldCancelRequest); + } + + /** + * TestAPI to allow us to set the folded states array, instead of reading from resources. + */ + @TestApi + void setFoldedStates(int[] foldedStates) { + mFoldedStates = foldedStates; + } + + @TestApi + void setDeviceStateManagerCallback( + DeviceStateManager.DeviceStateCallback deviceStateManagerCallback) { + mDeviceStateManagerCallback = deviceStateManagerCallback; + } + + @TestApi + void setAnimationRepeatCount(int repeatCount) { + mAnimationRepeatCount = repeatCount; + } + + private class DeviceStateManagerCallback implements DeviceStateManager.DeviceStateCallback { + @Override + public void onBaseStateChanged(int state) { + if (mStartedFolded && !isFoldedState(state)) { + // We've opened the device, we can close the overlay + mRearDisplayEducationDialog.dismiss(); + closeOverlayAndNotifyService(false); + } else if (!mStartedFolded && isFoldedState(state)) { + // We've closed the device, finish activity + mRearDisplayEducationDialog.dismiss(); + closeOverlayAndNotifyService(true); + } + } + + // We only care about physical device changes in this scenario + @Override + public void onStateChanged(int state) {} + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt index f4d59a8dd6a6..db0052a4d99e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt @@ -23,8 +23,11 @@ import android.view.ViewStub import android.view.WindowManager import android.widget.AdapterView import android.widget.ArrayAdapter +import android.widget.ImageView import android.widget.Spinner import android.widget.TextView +import androidx.annotation.ColorRes +import androidx.annotation.DrawableRes import androidx.annotation.LayoutRes import androidx.annotation.StringRes import com.android.systemui.R @@ -34,7 +37,9 @@ import com.android.systemui.statusbar.phone.SystemUIDialog open class BaseScreenSharePermissionDialog( context: Context?, private val screenShareOptions: List<ScreenShareOption>, - private val appName: String? + private val appName: String?, + @DrawableRes private val dialogIconDrawable: Int? = null, + @ColorRes private val dialogIconTint: Int? = null ) : SystemUIDialog(context), AdapterView.OnItemSelectedListener { private lateinit var dialogTitle: TextView private lateinit var startButton: TextView @@ -53,10 +58,21 @@ open class BaseScreenSharePermissionDialog( warning = findViewById(R.id.text_warning) startButton = findViewById(R.id.button_start) findViewById<TextView>(R.id.button_cancel).setOnClickListener { dismiss() } + updateIcon() initScreenShareOptions() createOptionsView(getOptionsViewLayoutId()) } + private fun updateIcon() { + val icon = findViewById<ImageView>(R.id.screen_share_dialog_icon) + if (dialogIconTint != null) { + icon.setColorFilter(context.getColor(dialogIconTint)) + } + if (dialogIconDrawable != null) { + icon.setImageDrawable(context.getDrawable(dialogIconDrawable)) + } + } + protected fun initScreenShareOptions() { selectedScreenShareOption = screenShareOptions.first() warning.text = warningText @@ -69,8 +85,12 @@ open class BaseScreenSharePermissionDialog( private fun initScreenShareSpinner() { val options = screenShareOptions.map { context.getString(it.spinnerText) }.toTypedArray() val adapter = - ArrayAdapter(context.applicationContext, android.R.layout.simple_spinner_item, options) - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + ArrayAdapter( + context.applicationContext, + R.layout.screen_share_dialog_spinner_text, + options + ) + adapter.setDropDownViewResource(R.layout.screen_share_dialog_spinner_item_text) screenShareModeSpinner = findViewById(R.id.screen_share_mode_spinner) screenShareModeSpinner.adapter = adapter screenShareModeSpinner.onItemSelectedListener = this diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt index 15b0bc4a356a..c5a82ce110de 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt @@ -23,11 +23,15 @@ import com.android.systemui.R class MediaProjectionPermissionDialog( context: Context?, private val onStartRecordingClicked: Runnable, - appName: String? -) : BaseScreenSharePermissionDialog(context, createOptionList(), appName) { + private val appName: String? +) : BaseScreenSharePermissionDialog(context, createOptionList(appName), appName) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setDialogTitle(R.string.media_projection_permission_dialog_title) + if (appName == null) { + setDialogTitle(R.string.media_projection_permission_dialog_system_service_title) + } else { + setDialogTitle(R.string.media_projection_permission_dialog_title) + } setStartButtonText(R.string.media_projection_permission_dialog_continue) setStartButtonOnClickListener { // Note that it is important to run this callback before dismissing, so that the @@ -38,17 +42,30 @@ class MediaProjectionPermissionDialog( } companion object { - private fun createOptionList(): List<ScreenShareOption> { + private fun createOptionList(appName: String?): List<ScreenShareOption> { + val singleAppWarningText = + if (appName == null) { + R.string.media_projection_permission_dialog_system_service_warning_single_app + } else { + R.string.media_projection_permission_dialog_warning_single_app + } + val entireScreenWarningText = + if (appName == null) { + R.string.media_projection_permission_dialog_system_service_warning_entire_screen + } else { + R.string.media_projection_permission_dialog_warning_entire_screen + } + return listOf( ScreenShareOption( - SINGLE_APP, - R.string.media_projection_permission_dialog_option_single_app, - R.string.media_projection_permission_dialog_warning_single_app + mode = ENTIRE_SCREEN, + spinnerText = R.string.media_projection_permission_dialog_option_entire_screen, + warningText = entireScreenWarningText ), ScreenShareOption( - ENTIRE_SCREEN, - R.string.media_projection_permission_dialog_option_entire_screen, - R.string.media_projection_permission_dialog_warning_entire_screen + mode = SINGLE_APP, + spinnerText = R.string.media_projection_permission_dialog_option_single_app, + warningText = singleAppWarningText ) ) } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt index 19bb15a5c2d8..44b18ec4639b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt @@ -46,7 +46,14 @@ class ScreenRecordPermissionDialog( private val dialogLaunchAnimator: DialogLaunchAnimator, private val userContextProvider: UserContextProvider, private val onStartRecordingClicked: Runnable? -) : BaseScreenSharePermissionDialog(context, createOptionList(), null) { +) : + BaseScreenSharePermissionDialog( + context, + createOptionList(), + null, + R.drawable.ic_screenrecord, + R.color.screenrecord_icon_color + ) { private lateinit var tapsSwitch: Switch private lateinit var tapsView: View private lateinit var audioSwitch: Switch @@ -169,14 +176,14 @@ class ScreenRecordPermissionDialog( private fun createOptionList(): List<ScreenShareOption> { return listOf( ScreenShareOption( - SINGLE_APP, - R.string.screenrecord_option_single_app, - R.string.screenrecord_warning_single_app - ), - ScreenShareOption( ENTIRE_SCREEN, R.string.screenrecord_option_entire_screen, R.string.screenrecord_warning_entire_screen + ), + ScreenShareOption( + SINGLE_APP, + R.string.screenrecord_option_single_app, + R.string.screenrecord_warning_single_app ) ) } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt index 914d29a52b53..3d39fd82ac63 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenShareOption.kt @@ -20,11 +20,11 @@ import androidx.annotation.StringRes import kotlin.annotation.Retention @Retention(AnnotationRetention.SOURCE) -@IntDef(SINGLE_APP, ENTIRE_SCREEN) +@IntDef(ENTIRE_SCREEN, SINGLE_APP) annotation class ScreenShareMode -const val SINGLE_APP = 0 -const val ENTIRE_SCREEN = 1 +const val ENTIRE_SCREEN = 0 +const val SINGLE_APP = 1 class ScreenShareOption( @ScreenShareMode val mode: Int, diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt index 31e44646859f..5e47d6dd5b76 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt @@ -19,6 +19,7 @@ package com.android.systemui.shade import android.annotation.IdRes import android.app.StatusBarManager import android.content.res.Configuration +import android.os.Bundle import android.os.Trace import android.os.Trace.TRACE_TAG_APP import android.util.Pair @@ -34,6 +35,8 @@ import com.android.systemui.animation.Interpolators import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController +import com.android.systemui.demomode.DemoMode +import com.android.systemui.demomode.DemoModeController import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags @@ -53,6 +56,7 @@ import com.android.systemui.statusbar.phone.StatusIconContainer import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER +import com.android.systemui.statusbar.policy.Clock import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.VariableDateView import com.android.systemui.statusbar.policy.VariableDateViewController @@ -89,7 +93,8 @@ class LargeScreenShadeHeaderController @Inject constructor( private val dumpManager: DumpManager, private val featureFlags: FeatureFlags, private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder, - private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager + private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager, + private val demoModeController: DemoModeController ) : ViewController<View>(header), Dumpable { companion object { @@ -126,7 +131,7 @@ class LargeScreenShadeHeaderController @Inject constructor( private lateinit var qsCarrierGroupController: QSCarrierGroupController private val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon) - private val clock: TextView = header.findViewById(R.id.clock) + private val clock: Clock = header.findViewById(R.id.clock) private val date: TextView = header.findViewById(R.id.date) private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons) private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group) @@ -212,6 +217,14 @@ class LargeScreenShadeHeaderController @Inject constructor( view.onApplyWindowInsets(insets) } + private val demoModeReceiver = object : DemoMode { + override fun demoCommands() = listOf(DemoMode.COMMAND_CLOCK) + override fun dispatchDemoCommand(command: String, args: Bundle) = + clock.dispatchDemoCommand(command, args) + override fun onDemoModeStarted() = clock.onDemoModeStarted() + override fun onDemoModeFinished() = clock.onDemoModeFinished() + } + private val chipVisibilityListener: ChipVisibilityListener = object : ChipVisibilityListener { override fun onChipVisibilityRefreshed(visible: Boolean) { if (header is MotionLayout) { @@ -300,6 +313,7 @@ class LargeScreenShadeHeaderController @Inject constructor( dumpManager.registerDumpable(this) configurationController.addCallback(configurationControllerListener) + demoModeController.addCallback(demoModeReceiver) updateVisibility() updateTransition() @@ -309,6 +323,7 @@ class LargeScreenShadeHeaderController @Inject constructor( privacyIconsController.chipVisibilityListener = null dumpManager.unregisterDumpable(this::class.java.simpleName) configurationController.removeCallback(configurationControllerListener) + demoModeController.removeCallback(demoModeReceiver) } fun disable(state1: Int, state2: Int, animate: Boolean) { @@ -521,4 +536,7 @@ class LargeScreenShadeHeaderController @Inject constructor( updateConstraints(LARGE_SCREEN_HEADER_CONSTRAINT, updates.largeScreenConstraintsChanges) } } + + @VisibleForTesting + internal fun simulateViewDetached() = this.onViewDetached() } diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 7fbdeca3963a..a3d9965e9397 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -2072,6 +2072,13 @@ public final class NotificationPanelViewController implements Dumpable { mInitialTouchX = x; initVelocityTracker(); trackMovement(event); + float qsExpansionFraction = computeQsExpansionFraction(); + // Intercept the touch if QS is between fully collapsed and fully expanded state + if (qsExpansionFraction > 0.0 && qsExpansionFraction < 1.0) { + mShadeLog.logMotionEvent(event, + "onQsIntercept: down action, QS partially expanded/collapsed"); + return true; + } if (mKeyguardShowing && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) { // Dragging down on the lockscreen statusbar should prohibit other interactions @@ -2324,6 +2331,13 @@ public final class NotificationPanelViewController implements Dumpable { if (!isFullyCollapsed()) { handleQsDown(event); } + // defer touches on QQS to shade while shade is collapsing. Added margin for error + // as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS. + if (computeQsExpansionFraction() <= 0.01 && getExpandedFraction() < 1.0) { + mShadeLog.logMotionEvent(event, + "handleQsTouch: QQS touched while shade collapsing"); + mQsTracking = false; + } if (!mQsExpandImmediate && mQsTracking) { onQsTouch(event); if (!mConflictingQsExpansionGesture && !mSplitShadeEnabled) { @@ -2564,7 +2578,6 @@ public final class NotificationPanelViewController implements Dumpable { // Reset scroll position and apply that position to the expanded height. float height = mQsExpansionHeight; setQsExpansionHeight(height); - updateExpandedHeightToMaxHeight(); mNotificationStackScrollLayoutController.checkSnoozeLeavebehind(); // When expanding QS, let's authenticate the user if possible, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java index be0818339b74..01ca66742287 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -122,6 +122,7 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn ActivityOptions options = getDefaultActivityOptions(animationAdapter); options.setLaunchDisplayId(displayId); options.setCallerDisplayId(displayId); + options.setPendingIntentBackgroundActivityLaunchAllowed(true); return options.toBundle(); } @@ -145,6 +146,7 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn : ActivityOptions.SourceInfo.TYPE_NOTIFICATION, eventTime); options.setLaunchDisplayId(displayId); options.setCallerDisplayId(displayId); + options.setPendingIntentBackgroundActivityLaunchAllowed(true); return options.toBundle(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 5efd4603500f..32ea8d6fa695 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -977,6 +977,11 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // Lastly, call to the icon policy to install/update all the icons. mIconPolicy.init(); + // Based on teamfood flag, turn predictive back dispatch on at runtime. + if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_SYSUI)) { + mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true); + } + mKeyguardStateController.addCallback(new KeyguardStateController.Callback() { @Override public void onUnlockedChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt index fcd1b8abefe4..0662fb3d52b9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.pipeline.dagger +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepositoryImpl import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository @@ -32,6 +35,7 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiReposito import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl import dagger.Binds import dagger.Module +import dagger.Provides @Module abstract class StatusBarPipelineModule { @@ -57,4 +61,15 @@ abstract class StatusBarPipelineModule { @Binds abstract fun mobileIconsInteractor(impl: MobileIconsInteractorImpl): MobileIconsInteractor + + @Module + companion object { + @JvmStatic + @Provides + @SysUISingleton + @WifiTableLog + fun provideWifiTableLogBuffer(factory: TableLogBufferFactory): TableLogBuffer { + return factory.create("WifiTableLog", 100) + } + } } diff --git a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiRoboBase.java b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiTableLog.kt index d9686bbeb0cd..ac395a9d521b 100644 --- a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiRoboBase.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiTableLog.kt @@ -14,14 +14,12 @@ * limitations under the License. */ -package com.android.systemui.robotests; +package com.android.systemui.statusbar.pipeline.dagger -import android.content.Context; +import javax.inject.Qualifier -import androidx.test.InstrumentationRegistry; - -public class SysuiRoboBase { - public Context getContext() { - return InstrumentationRegistry.getContext(); - } -} +/** Wifi logs in table format. */ +@Qualifier +@MustBeDocumented +@kotlin.annotation.Retention(AnnotationRetention.RUNTIME) +annotation class WifiTableLog diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt index 062c3d1a4b10..8436b13d7038 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt @@ -17,12 +17,30 @@ package com.android.systemui.statusbar.pipeline.wifi.data.model import androidx.annotation.VisibleForTesting +import com.android.systemui.log.table.TableRowLogger +import com.android.systemui.log.table.Diffable /** Provides information about the current wifi network. */ -sealed class WifiNetworkModel { +sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { + /** A model representing that we have no active wifi network. */ object Inactive : WifiNetworkModel() { override fun toString() = "WifiNetwork.Inactive" + + override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) { + if (prevVal is Inactive) { + return + } + row.logChange(COL_NETWORK_TYPE, TYPE_INACTIVE) + + if (prevVal is CarrierMerged) { + // The only difference between CarrierMerged and Inactive is the type + return + } + + // When changing from Active to Inactive, we need to log diffs to all the fields. + logDiffsFromActiveToNotActive(prevVal as Active, row) + } } /** @@ -33,6 +51,21 @@ sealed class WifiNetworkModel { */ object CarrierMerged : WifiNetworkModel() { override fun toString() = "WifiNetwork.CarrierMerged" + + override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) { + if (prevVal is CarrierMerged) { + return + } + row.logChange(COL_NETWORK_TYPE, TYPE_CARRIER_MERGED) + + if (prevVal is Inactive) { + // The only difference between CarrierMerged and Inactive is the type. + return + } + + // When changing from Active to CarrierMerged, we need to log diffs to all the fields. + logDiffsFromActiveToNotActive(prevVal as Active, row) + } } /** Provides information about an active wifi network. */ @@ -76,6 +109,41 @@ sealed class WifiNetworkModel { } } + override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) { + if (prevVal !is Active) { + row.logChange(COL_NETWORK_TYPE, TYPE_ACTIVE) + } + + if (prevVal !is Active || prevVal.networkId != networkId) { + row.logChange(COL_NETWORK_ID, networkId) + } + if (prevVal !is Active || prevVal.isValidated != isValidated) { + row.logChange(COL_VALIDATED, isValidated) + } + if (prevVal !is Active || prevVal.level != level) { + row.logChange(COL_LEVEL, level ?: LEVEL_DEFAULT) + } + if (prevVal !is Active || prevVal.ssid != ssid) { + row.logChange(COL_SSID, ssid) + } + + // TODO(b/238425913): The passpoint-related values are frequently never used, so it + // would be great to not log them when they're not used. + if (prevVal !is Active || prevVal.isPasspointAccessPoint != isPasspointAccessPoint) { + row.logChange(COL_PASSPOINT_ACCESS_POINT, isPasspointAccessPoint) + } + if (prevVal !is Active || + prevVal.isOnlineSignUpForPasspointAccessPoint != + isOnlineSignUpForPasspointAccessPoint) { + row.logChange(COL_ONLINE_SIGN_UP, isOnlineSignUpForPasspointAccessPoint) + } + if (prevVal !is Active || + prevVal.passpointProviderFriendlyName != passpointProviderFriendlyName) { + row.logChange(COL_PASSPOINT_NAME, passpointProviderFriendlyName) + } + } + + override fun toString(): String { // Only include the passpoint-related values in the string if we have them. (Most // networks won't have them so they'll be mostly clutter.) @@ -101,4 +169,37 @@ sealed class WifiNetworkModel { internal const val MAX_VALID_LEVEL = 4 } } + + internal fun logDiffsFromActiveToNotActive(prevActive: Active, row: TableRowLogger) { + row.logChange(COL_NETWORK_ID, NETWORK_ID_DEFAULT) + row.logChange(COL_VALIDATED, false) + row.logChange(COL_LEVEL, LEVEL_DEFAULT) + row.logChange(COL_SSID, null) + + if (prevActive.isPasspointAccessPoint) { + row.logChange(COL_PASSPOINT_ACCESS_POINT, false) + } + if (prevActive.isOnlineSignUpForPasspointAccessPoint) { + row.logChange(COL_ONLINE_SIGN_UP, false) + } + if (prevActive.passpointProviderFriendlyName != null) { + row.logChange(COL_PASSPOINT_NAME, null) + } + } } + +const val TYPE_CARRIER_MERGED = "CarrierMerged" +const val TYPE_INACTIVE = "Inactive" +const val TYPE_ACTIVE = "Active" + +const val COL_NETWORK_TYPE = "type" +const val COL_NETWORK_ID = "networkId" +const val COL_VALIDATED = "isValidated" +const val COL_LEVEL = "level" +const val COL_SSID = "ssid" +const val COL_PASSPOINT_ACCESS_POINT = "isPasspointAccessPoint" +const val COL_ONLINE_SIGN_UP = "isOnlineSignUpForPasspointAccessPoint" +const val COL_PASSPOINT_NAME = "passpointProviderFriendlyName" + +const val LEVEL_DEFAULT = -1 +const val NETWORK_ID_DEFAULT = -1 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt index 93448c1dee0e..a6635361cb3c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt @@ -36,6 +36,9 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable +import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange @@ -82,6 +85,7 @@ class WifiRepositoryImpl @Inject constructor( broadcastDispatcher: BroadcastDispatcher, connectivityManager: ConnectivityManager, logger: ConnectivityPipelineLogger, + @WifiTableLog wifiTableLogBuffer: TableLogBuffer, @Main mainExecutor: Executor, @Application scope: CoroutineScope, wifiManager: WifiManager?, @@ -199,6 +203,12 @@ class WifiRepositoryImpl @Inject constructor( awaitClose { connectivityManager.unregisterNetworkCallback(callback) } } + .distinctUntilChanged() + .logDiffsForTable( + wifiTableLogBuffer, + columnPrefix = "wifiNetwork", + initialValue = WIFI_NETWORK_DEFAULT, + ) // There will be multiple wifi icons in different places that will frequently // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures that // new subscribes will get the latest value immediately upon subscription. Otherwise, the diff --git a/packages/SystemUI/tests/robolectric/config/robolectric.properties b/packages/SystemUI/tests/robolectric/config/robolectric.properties deleted file mode 100644 index 2a75bd98bfe8..000000000000 --- a/packages/SystemUI/tests/robolectric/config/robolectric.properties +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (C) 2022 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -sdk=NEWEST_SDK
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsEnrollViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsEnrollViewTest.java new file mode 100644 index 000000000000..60a02582269c --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsEnrollViewTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.biometrics; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.res.Configuration; +import android.graphics.Color; +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class UdfpsEnrollViewTest extends SysuiTestCase { + + private static String ENROLL_PROGRESS_COLOR_LIGHT = "#699FF3"; + private static String ENROLL_PROGRESS_COLOR_DARK = "#7DA7F1"; + + @Test + public void fingerprintUdfpsEnroll_usesCorrectThemeCheckmarkFillColor() { + final Configuration config = mContext.getResources().getConfiguration(); + final boolean isDarkThemeOn = (config.uiMode & Configuration.UI_MODE_NIGHT_MASK) + == Configuration.UI_MODE_NIGHT_YES; + final int currentColor = mContext.getColor(R.color.udfps_enroll_progress); + + assertThat(currentColor).isEqualTo(Color.parseColor(isDarkThemeOn + ? ENROLL_PROGRESS_COLOR_DARK : ENROLL_PROGRESS_COLOR_LIGHT)); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt index 98ff8d1d8845..c677f19f93e5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt @@ -31,6 +31,7 @@ import android.service.controls.ControlsProviderService import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.settingslib.applications.ServiceListing +import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.dump.DumpManager @@ -110,6 +111,12 @@ class ControlsListingControllerImplTest : SysuiTestCase() { .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED) mContext.setMockPackageManager(packageManager) + mContext.orCreateTestableResources + .addOverride( + R.array.config_controlsPreferredPackages, + arrayOf(componentName.packageName) + ) + // Return true by default, we'll test the false path `when`(featureFlags.isEnabled(USE_APP_PANELS)).thenReturn(true) @@ -482,6 +489,35 @@ class ControlsListingControllerImplTest : SysuiTestCase() { } @Test + fun testPackageNotPreferred_nullPanel() { + mContext.orCreateTestableResources + .addOverride(R.array.config_controlsPreferredPackages, arrayOf<String>()) + + val serviceInfo = ServiceInfo( + componentName, + activityName + ) + + `when`(packageManager.getComponentEnabledSetting(eq(activityName))) + .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED) + + setUpQueryResult(listOf( + ActivityInfo( + activityName, + exported = true, + permission = Manifest.permission.BIND_CONTROLS + ) + )) + + val list = listOf(serviceInfo) + serviceListingCallbackCaptor.value.onServicesReloaded(list) + + executor.runAllReady() + + assertNull(controller.getCurrentServices()[0].panelActivity) + } + + @Test fun testListingsNotModifiedByCallback() { // This test checks that if the list passed to the callback is modified, it has no effect // in the resulting services diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt new file mode 100644 index 000000000000..cda701819d60 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.keyguard.data.quickaffordance + +import android.content.Context +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.common.shared.model.Icon +import com.android.systemui.keyguard.shared.quickaffordance.ActivationState +import com.android.systemui.statusbar.policy.FlashlightController +import com.android.systemui.utils.leaks.FakeFlashlightController +import com.android.systemui.utils.leaks.LeakCheckedTest +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(JUnit4::class) +class FlashlightQuickAffordanceConfigTest : LeakCheckedTest() { + + @Mock private lateinit var context: Context + private lateinit var flashlightController: FakeFlashlightController + private lateinit var underTest : FlashlightQuickAffordanceConfig + + @Before + fun setUp() { + injectLeakCheckedDependency(FlashlightController::class.java) + MockitoAnnotations.initMocks(this) + + flashlightController = SysuiLeakCheck().getLeakChecker(FlashlightController::class.java) as FakeFlashlightController + underTest = FlashlightQuickAffordanceConfig(context, flashlightController) + } + + @Test + fun `flashlight is off -- triggered -- icon is on and active`() = runTest { + //given + flashlightController.isEnabled = false + flashlightController.isAvailable = true + val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() + val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values)} + + //when + underTest.onTriggered(null) + val lastValue = values.last() + + //then + assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) + assertEquals(R.drawable.ic_flashlight_on, + ((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).icon as? Icon.Resource)?.res) + job.cancel() + } + + @Test + fun `flashlight is on -- triggered -- icon is off and inactive`() = runTest { + //given + flashlightController.isEnabled = true + flashlightController.isAvailable = true + val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() + val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values)} + + //when + underTest.onTriggered(null) + val lastValue = values.last() + + //then + assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) + assertEquals(R.drawable.ic_flashlight_off, + ((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).icon as? Icon.Resource)?.res) + job.cancel() + } + + @Test + fun `flashlight is on -- receives error -- icon is off and inactive`() = runTest { + //given + flashlightController.isEnabled = true + flashlightController.isAvailable = false + val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() + val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values)} + + //when + flashlightController.onFlashlightError() + val lastValue = values.last() + + //then + assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) + assertEquals(R.drawable.ic_flashlight_off, + ((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).icon as? Icon.Resource)?.res) + job.cancel() + } + + @Test + fun `flashlight availability now off -- hidden`() = runTest { + //given + flashlightController.isEnabled = true + flashlightController.isAvailable = false + val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() + val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values)} + + //when + flashlightController.onFlashlightAvailabilityChanged(false) + val lastValue = values.last() + + //then + assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Hidden) + job.cancel() + } + + @Test + fun `flashlight availability now on -- flashlight on -- inactive and icon off`() = runTest { + //given + flashlightController.isEnabled = true + flashlightController.isAvailable = false + val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() + val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values)} + + //when + flashlightController.onFlashlightAvailabilityChanged(true) + val lastValue = values.last() + + //then + assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) + assertTrue((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).activationState is ActivationState.Active) + assertEquals(R.drawable.ic_flashlight_on, (lastValue.icon as? Icon.Resource)?.res) + job.cancel() + } + + @Test + fun `flashlight availability now on -- flashlight off -- inactive and icon off`() = runTest { + //given + flashlightController.isEnabled = false + flashlightController.isAvailable = false + val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() + val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values)} + + //when + flashlightController.onFlashlightAvailabilityChanged(true) + val lastValue = values.last() + + //then + assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) + assertTrue((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).activationState is ActivationState.Inactive) + assertEquals(R.drawable.ic_flashlight_off, (lastValue.icon as? Icon.Resource)?.res) + job.cancel() + } + + @Test + fun `flashlight available -- picker state default`() = runTest { + //given + flashlightController.isAvailable = true + + //when + val result = underTest.getPickerScreenState() + + //then + assertTrue(result is KeyguardQuickAffordanceConfig.PickerScreenState.Default) + } + + @Test + fun `flashlight not available -- picker state unavailable`() = runTest { + //given + flashlightController.isAvailable = false + + //when + val result = underTest.getPickerScreenState() + + //then + assertTrue(result is KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt new file mode 100644 index 000000000000..432764a7de8f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.table + +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +@SmallTest +class TableChangeTest : SysuiTestCase() { + + @Test + fun setString_isString() { + val underTest = TableChange() + + underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName") + underTest.set("fakeValue") + + assertThat(underTest.hasData()).isTrue() + assertThat(underTest.getVal()).isEqualTo("fakeValue") + } + + @Test + fun setBoolean_isBoolean() { + val underTest = TableChange() + + underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName") + underTest.set(true) + + assertThat(underTest.hasData()).isTrue() + assertThat(underTest.getVal()).isEqualTo("true") + } + + @Test + fun setInt_isInt() { + val underTest = TableChange() + + underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName") + underTest.set(8900) + + assertThat(underTest.hasData()).isTrue() + assertThat(underTest.getVal()).isEqualTo("8900") + } + + @Test + fun setThenReset_isEmpty() { + val underTest = TableChange() + + underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName") + underTest.set(8900) + underTest.reset(timestamp = 0, columnPrefix = "prefix", columnName = "name") + + assertThat(underTest.hasData()).isFalse() + assertThat(underTest.getVal()).isEqualTo("null") + } + + @Test + fun getName_hasPrefix() { + val underTest = TableChange(columnPrefix = "fakePrefix", columnName = "fakeName") + + assertThat(underTest.getName()).contains("fakePrefix") + assertThat(underTest.getName()).contains("fakeName") + } + + @Test + fun getName_noPrefix() { + val underTest = TableChange(columnPrefix = "", columnName = "fakeName") + + assertThat(underTest.getName()).contains("fakeName") + } + + @Test + fun resetThenSet_hasNewValue() { + val underTest = TableChange() + + underTest.reset(timestamp = 100, columnPrefix = "prefix", columnName = "original") + underTest.set("fakeValue") + underTest.reset(timestamp = 0, columnPrefix = "", columnName = "updated") + underTest.set(8900) + + assertThat(underTest.hasData()).isTrue() + assertThat(underTest.getName()).contains("updated") + assertThat(underTest.getName()).doesNotContain("prefix") + assertThat(underTest.getName()).doesNotContain("original") + assertThat(underTest.getVal()).isEqualTo("8900") + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt new file mode 100644 index 000000000000..688c66ac80c9 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.table + +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import java.io.PrintWriter +import java.io.StringWriter +import org.junit.Before +import org.junit.Test + +@SmallTest +class TableLogBufferTest : SysuiTestCase() { + private lateinit var underTest: TableLogBuffer + + private lateinit var systemClock: FakeSystemClock + private lateinit var outputWriter: StringWriter + + @Before + fun setup() { + systemClock = FakeSystemClock() + outputWriter = StringWriter() + + underTest = TableLogBuffer(MAX_SIZE, NAME, systemClock) + } + + @Test(expected = IllegalArgumentException::class) + fun maxSizeZero_throwsException() { + TableLogBuffer(maxSize = 0, "name", systemClock) + } + + @Test + fun dumpChanges_strChange_logsFromNext() { + systemClock.setCurrentTimeMillis(100L) + + val prevDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("stringValChange", "prevStringVal") + } + } + val nextDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("stringValChange", "newStringVal") + } + } + + underTest.logDiffs("prefix", prevDiffable, nextDiffable) + + val dumpedString = dumpChanges() + + assertThat(dumpedString).contains("prefix") + assertThat(dumpedString).contains("stringValChange") + assertThat(dumpedString).contains("newStringVal") + assertThat(dumpedString).doesNotContain("prevStringVal") + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(100L)) + } + + @Test + fun dumpChanges_boolChange_logsFromNext() { + systemClock.setCurrentTimeMillis(100L) + + val prevDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("booleanValChange", false) + } + } + val nextDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("booleanValChange", true) + } + } + + underTest.logDiffs("prefix", prevDiffable, nextDiffable) + + val dumpedString = dumpChanges() + + assertThat(dumpedString).contains("prefix") + assertThat(dumpedString).contains("booleanValChange") + assertThat(dumpedString).contains("true") + assertThat(dumpedString).doesNotContain("false") + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(100L)) + } + + @Test + fun dumpChanges_intChange_logsFromNext() { + systemClock.setCurrentTimeMillis(100L) + + val prevDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("intValChange", 12345) + } + } + val nextDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("intValChange", 67890) + } + } + + underTest.logDiffs("prefix", prevDiffable, nextDiffable) + + val dumpedString = dumpChanges() + + assertThat(dumpedString).contains("prefix") + assertThat(dumpedString).contains("intValChange") + assertThat(dumpedString).contains("67890") + assertThat(dumpedString).doesNotContain("12345") + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(100L)) + } + + @Test + fun dumpChanges_noPrefix() { + systemClock.setCurrentTimeMillis(100L) + + val prevDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("booleanValChange", false) + } + } + val nextDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("booleanValChange", true) + } + } + + // WHEN there's a blank prefix + underTest.logDiffs("", prevDiffable, nextDiffable) + + val dumpedString = dumpChanges() + + // THEN the dump still works + assertThat(dumpedString).contains("booleanValChange") + assertThat(dumpedString).contains("true") + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(100L)) + } + + @Test + fun dumpChanges_multipleChangesForSameColumn_logs() { + lateinit var valToDump: String + + val diffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("valChange", valToDump) + } + } + + systemClock.setCurrentTimeMillis(12000L) + valToDump = "stateValue12" + underTest.logDiffs(columnPrefix = "", diffable, diffable) + + systemClock.setCurrentTimeMillis(20000L) + valToDump = "stateValue20" + underTest.logDiffs(columnPrefix = "", diffable, diffable) + + systemClock.setCurrentTimeMillis(40000L) + valToDump = "stateValue40" + underTest.logDiffs(columnPrefix = "", diffable, diffable) + + systemClock.setCurrentTimeMillis(45000L) + valToDump = "stateValue45" + underTest.logDiffs(columnPrefix = "", diffable, diffable) + + val dumpedString = dumpChanges() + + assertThat(dumpedString).contains("valChange") + assertThat(dumpedString).contains("stateValue12") + assertThat(dumpedString).contains("stateValue20") + assertThat(dumpedString).contains("stateValue40") + assertThat(dumpedString).contains("stateValue45") + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(12000L)) + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(20000L)) + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(40000L)) + assertThat(dumpedString).contains(TABLE_LOG_DATE_FORMAT.format(45000L)) + } + + @Test + fun dumpChanges_multipleChangesAtOnce_logs() { + systemClock.setCurrentTimeMillis(100L) + + val prevDiffable = object : TestDiffable() {} + val nextDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("status", "in progress") + row.logChange("connected", false) + } + } + + underTest.logDiffs(columnPrefix = "", prevDiffable, nextDiffable) + + val dumpedString = dumpChanges() + + assertThat(dumpedString).contains("status") + assertThat(dumpedString).contains("in progress") + assertThat(dumpedString).contains("connected") + assertThat(dumpedString).contains("false") + } + + @Test + fun dumpChanges_rotatesIfBufferIsFull() { + lateinit var valToDump: String + + val prevDiffable = object : TestDiffable() {} + val nextDiffable = + object : TestDiffable() { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) { + row.logChange("status", valToDump) + } + } + + for (i in 0 until MAX_SIZE + 3) { + valToDump = "testString[$i]" + underTest.logDiffs(columnPrefix = "", prevDiffable, nextDiffable) + } + + val dumpedString = dumpChanges() + + assertThat(dumpedString).doesNotContain("testString[0]") + assertThat(dumpedString).doesNotContain("testString[1]") + assertThat(dumpedString).doesNotContain("testString[2]") + assertThat(dumpedString).contains("testString[3]") + assertThat(dumpedString).contains("testString[${MAX_SIZE + 2}]") + } + + private fun dumpChanges(): String { + underTest.dumpChanges(PrintWriter(outputWriter)) + return outputWriter.toString() + } + + private abstract class TestDiffable : Diffable<TestDiffable> { + override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) {} + } +} + +private const val NAME = "TestTableBuffer" +private const val MAX_SIZE = 10 diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java index 6c03730e056e..1865ef64c5d5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java @@ -16,6 +16,7 @@ package com.android.systemui.navigationbar; +import static android.app.StatusBarManager.WINDOW_NAVIGATION_BAR; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR; @@ -47,6 +48,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.dump.DumpManager; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.settings.UserTracker; +import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -69,6 +71,10 @@ import dagger.Lazy; @SmallTest public class NavBarHelperTest extends SysuiTestCase { + private static final int DISPLAY_ID = 0; + private static final int WINDOW = WINDOW_NAVIGATION_BAR; + private static final int STATE_ID = 0; + @Mock AccessibilityManager mAccessibilityManager; @Mock @@ -93,6 +99,8 @@ public class NavBarHelperTest extends SysuiTestCase { DumpManager mDumpManager; @Mock NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater; + @Mock + CommandQueue mCommandQueue; private AccessibilityManager.AccessibilityServicesStateChangeListener mAccessibilityServicesStateChangeListener; @@ -114,7 +122,7 @@ public class NavBarHelperTest extends SysuiTestCase { mAccessibilityButtonModeObserver, mAccessibilityButtonTargetObserver, mSystemActions, mOverviewProxyService, mAssistManagerLazy, () -> Optional.of(mock(CentralSurfaces.class)), mock(KeyguardStateController.class), - mNavigationModeController, mUserTracker, mDumpManager); + mNavigationModeController, mUserTracker, mDumpManager, mCommandQueue); } @@ -241,6 +249,45 @@ public class NavBarHelperTest extends SysuiTestCase { ACCESSIBILITY_BUTTON_CLICKABLE_STATE); } + @Test + public void registerCommandQueueCallbacks() { + mNavBarHelper.init(); + verify(mCommandQueue, times(1)).addCallback(any()); + } + + @Test + public void saveMostRecentSysuiState() { + mNavBarHelper.init(); + mNavBarHelper.setWindowState(DISPLAY_ID, WINDOW, STATE_ID); + NavBarHelper.CurrentSysuiState state1 = mNavBarHelper.getCurrentSysuiState(); + + // Update window state + int newState = STATE_ID + 1; + mNavBarHelper.setWindowState(DISPLAY_ID, WINDOW, newState); + NavBarHelper.CurrentSysuiState state2 = mNavBarHelper.getCurrentSysuiState(); + + // Ensure we get most recent state back + assertThat(state1.mWindowState).isNotEqualTo(state2.mWindowState); + assertThat(state1.mWindowStateDisplayId).isEqualTo(state2.mWindowStateDisplayId); + assertThat(state2.mWindowState).isEqualTo(newState); + } + + @Test + public void ignoreNonNavbarSysuiState() { + mNavBarHelper.init(); + mNavBarHelper.setWindowState(DISPLAY_ID, WINDOW, STATE_ID); + NavBarHelper.CurrentSysuiState state1 = mNavBarHelper.getCurrentSysuiState(); + + // Update window state for other window type + int newState = STATE_ID + 1; + mNavBarHelper.setWindowState(DISPLAY_ID, WINDOW + 1, newState); + NavBarHelper.CurrentSysuiState state2 = mNavBarHelper.getCurrentSysuiState(); + + // Ensure we get first state back + assertThat(state2.mWindowState).isEqualTo(state1.mWindowState); + assertThat(state2.mWindowState).isNotEqualTo(newState); + } + private List<String> createFakeShortcutTargets() { return new ArrayList<>(List.of("a", "b", "c", "d")); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index c1fa9b39f50b..f43a34f6e89b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -247,7 +247,7 @@ public class NavigationBarTest extends SysuiTestCase { mSystemActions, mOverviewProxyService, () -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces), mKeyguardStateController, mock(NavigationModeController.class), - mock(UserTracker.class), mock(DumpManager.class))); + mock(UserTracker.class), mock(DumpManager.class), mock(CommandQueue.class))); mNavigationBar = createNavBar(mContext); mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal); }); @@ -438,6 +438,12 @@ public class NavigationBarTest extends SysuiTestCase { verify(mNavigationBarView).setVisibility(View.INVISIBLE); } + @Test + public void testOnInit_readCurrentSysuiState() { + mNavigationBar.init(); + verify(mNavBarHelper, times(1)).getCurrentSysuiState(); + } + private NavigationBar createNavBar(Context context) { DeviceProvisionedController deviceProvisionedController = mock(DeviceProvisionedController.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java new file mode 100644 index 000000000000..ea0e454f0b5d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.reardisplay; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; + +import android.hardware.devicestate.DeviceStateManager; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.View; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import java.util.concurrent.Executor; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class RearDisplayDialogControllerTest extends SysuiTestCase { + + @Mock + private CommandQueue mCommandQueue; + + private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); + + + private static final int CLOSED_BASE_STATE = 0; + private static final int OPEN_BASE_STATE = 1; + + @Test + public void testClosedDialogIsShown() { + RearDisplayDialogController controller = new RearDisplayDialogController(mContext, + mCommandQueue, mFakeExecutor); + controller.setDeviceStateManagerCallback(new TestDeviceStateManagerCallback()); + controller.setFoldedStates(new int[]{0}); + controller.setAnimationRepeatCount(0); + + controller.showRearDisplayDialog(CLOSED_BASE_STATE); + assertTrue(controller.mRearDisplayEducationDialog.isShowing()); + View deviceOpenedWarningTextView = controller.mRearDisplayEducationDialog.findViewById( + R.id.rear_display_warning_text_view); + assertNull(deviceOpenedWarningTextView); + } + + @Test + public void testOpenDialogIsShown() { + RearDisplayDialogController controller = new RearDisplayDialogController(mContext, + mCommandQueue, mFakeExecutor); + controller.setDeviceStateManagerCallback(new TestDeviceStateManagerCallback()); + controller.setFoldedStates(new int[]{0}); + controller.setAnimationRepeatCount(0); + + controller.showRearDisplayDialog(OPEN_BASE_STATE); + + assertTrue(controller.mRearDisplayEducationDialog.isShowing()); + View deviceOpenedWarningTextView = controller.mRearDisplayEducationDialog.findViewById( + R.id.rear_display_warning_text_view); + assertNotNull(deviceOpenedWarningTextView); + } + + /** + * Empty device state manager callbacks, so we can verify that the correct + * dialogs are being created regardless of device state of the test device. + */ + private static class TestDeviceStateManagerCallback implements + DeviceStateManager.DeviceStateCallback { + + @Override + public void onStateChanged(int state) { } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt index e1007faae88b..858d0e7b94d0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt @@ -35,6 +35,8 @@ import com.android.systemui.animation.Interpolators import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController +import com.android.systemui.demomode.DemoMode +import com.android.systemui.demomode.DemoModeController import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags @@ -50,10 +52,12 @@ import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_ import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusIconContainer +import com.android.systemui.statusbar.policy.Clock import com.android.systemui.statusbar.policy.FakeConfigurationController import com.android.systemui.statusbar.policy.VariableDateView import com.android.systemui.statusbar.policy.VariableDateViewController import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock @@ -104,7 +108,7 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { @Mock private lateinit var featureFlags: FeatureFlags @Mock - private lateinit var clock: TextView + private lateinit var clock: Clock @Mock private lateinit var date: VariableDateView @Mock @@ -138,6 +142,7 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { private lateinit var qsConstraints: ConstraintSet @Mock private lateinit var largeScreenConstraints: ConstraintSet + @Mock private lateinit var demoModeController: DemoModeController @JvmField @Rule val mockitoRule = MockitoJUnit.rule() @@ -146,10 +151,12 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { private lateinit var controller: LargeScreenShadeHeaderController private lateinit var carrierIconSlots: List<String> private val configurationController = FakeConfigurationController() + private lateinit var demoModeControllerCapture: ArgumentCaptor<DemoMode> @Before fun setUp() { - whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock) + demoModeControllerCapture = argumentCaptor<DemoMode>() + whenever<Clock>(view.findViewById(R.id.clock)).thenReturn(clock) whenever(clock.context).thenReturn(mockedContext) whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date) @@ -195,7 +202,8 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { dumpManager, featureFlags, qsCarrierGroupControllerBuilder, - combinedShadeHeadersConstraintManager + combinedShadeHeadersConstraintManager, + demoModeController ) whenever(view.isAttachedToWindow).thenReturn(true) controller.init() @@ -617,6 +625,21 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { } @Test + fun demoMode_attachDemoMode() { + verify(demoModeController).addCallback(capture(demoModeControllerCapture)) + demoModeControllerCapture.value.onDemoModeStarted() + verify(clock).onDemoModeStarted() + } + + @Test + fun demoMode_detachDemoMode() { + controller.simulateViewDetached() + verify(demoModeController).removeCallback(capture(demoModeControllerCapture)) + demoModeControllerCapture.value.onDemoModeFinished() + verify(clock).onDemoModeFinished() + } + + @Test fun animateOutOnStartCustomizing() { val animator = Mockito.mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF) val duration = 1000L diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt index 90ae693db955..b4c8f981b760 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt @@ -13,6 +13,8 @@ import com.android.systemui.animation.Interpolators import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController +import com.android.systemui.demomode.DemoMode +import com.android.systemui.demomode.DemoModeController import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags @@ -22,9 +24,12 @@ import com.android.systemui.qs.carrier.QSCarrierGroupController import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusIconContainer +import com.android.systemui.statusbar.policy.Clock import com.android.systemui.statusbar.policy.FakeConfigurationController import com.android.systemui.statusbar.policy.VariableDateViewController import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.capture import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before @@ -52,7 +57,7 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder @Mock private lateinit var featureFlags: FeatureFlags - @Mock private lateinit var clock: TextView + @Mock private lateinit var clock: Clock @Mock private lateinit var date: TextView @Mock private lateinit var carrierGroup: QSCarrierGroup @Mock private lateinit var batteryMeterView: BatteryMeterView @@ -66,6 +71,7 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { CombinedShadeHeadersConstraintManager @Mock private lateinit var mockedContext: Context + @Mock private lateinit var demoModeController: DemoModeController @JvmField @Rule val mockitoRule = MockitoJUnit.rule() var viewVisibility = View.GONE @@ -76,7 +82,7 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { @Before fun setup() { - whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock) + whenever<Clock>(view.findViewById(R.id.clock)).thenReturn(clock) whenever(clock.context).thenReturn(mockedContext) whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date) whenever(date.context).thenReturn(mockedContext) @@ -111,8 +117,9 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { dumpManager, featureFlags, qsCarrierGroupControllerBuilder, - combinedShadeHeadersConstraintManager - ) + combinedShadeHeadersConstraintManager, + demoModeController + ) whenever(view.isAttachedToWindow).thenReturn(true) mLargeScreenShadeHeaderController.init() carrierIconSlots = listOf( @@ -230,4 +237,21 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { verify(animator).setInterpolator(Interpolators.ALPHA_IN) verify(animator).start() } + + @Test + fun demoMode_attachDemoMode() { + val cb = argumentCaptor<DemoMode>() + verify(demoModeController).addCallback(capture(cb)) + cb.value.onDemoModeStarted() + verify(clock).onDemoModeStarted() + } + + @Test + fun demoMode_detachDemoMode() { + mLargeScreenShadeHeaderController.simulateViewDetached() + val cb = argumentCaptor<DemoMode>() + verify(demoModeController).removeCallback(capture(cb)) + cb.value.onDemoModeFinished() + verify(clock).onDemoModeFinished() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt index 3d29d2b2c3c8..30fd308433e4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt @@ -18,8 +18,10 @@ package com.android.systemui.statusbar.pipeline.wifi.data.model import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.log.table.TableRowLogger import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Active.Companion.MAX_VALID_LEVEL import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Active.Companion.MIN_VALID_LEVEL +import com.google.common.truth.Truth.assertThat import org.junit.Test @SmallTest @@ -48,6 +50,125 @@ class WifiNetworkModelTest : SysuiTestCase() { WifiNetworkModel.Active(NETWORK_ID, level = MAX_VALID_LEVEL + 1) } + // Non-exhaustive logDiffs test -- just want to make sure the logging logic isn't totally broken + + @Test + fun logDiffs_inactiveToActive_logsAllActiveFields() { + val logger = TestLogger() + val activeNetwork = + WifiNetworkModel.Active( + networkId = 5, + isValidated = true, + level = 3, + ssid = "Test SSID" + ) + + activeNetwork.logDiffs(prevVal = WifiNetworkModel.Inactive, logger) + + assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_ACTIVE)) + assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, "5")) + assertThat(logger.changes).contains(Pair(COL_VALIDATED, "true")) + assertThat(logger.changes).contains(Pair(COL_LEVEL, "3")) + assertThat(logger.changes).contains(Pair(COL_SSID, "Test SSID")) + } + @Test + fun logDiffs_activeToInactive_resetsAllActiveFields() { + val logger = TestLogger() + val activeNetwork = + WifiNetworkModel.Active( + networkId = 5, + isValidated = true, + level = 3, + ssid = "Test SSID" + ) + + WifiNetworkModel.Inactive.logDiffs(prevVal = activeNetwork, logger) + + assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_INACTIVE)) + assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, NETWORK_ID_DEFAULT.toString())) + assertThat(logger.changes).contains(Pair(COL_VALIDATED, "false")) + assertThat(logger.changes).contains(Pair(COL_LEVEL, LEVEL_DEFAULT.toString())) + assertThat(logger.changes).contains(Pair(COL_SSID, "null")) + } + + @Test + fun logDiffs_carrierMergedToActive_logsAllActiveFields() { + val logger = TestLogger() + val activeNetwork = + WifiNetworkModel.Active( + networkId = 5, + isValidated = true, + level = 3, + ssid = "Test SSID" + ) + + activeNetwork.logDiffs(prevVal = WifiNetworkModel.CarrierMerged, logger) + + assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_ACTIVE)) + assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, "5")) + assertThat(logger.changes).contains(Pair(COL_VALIDATED, "true")) + assertThat(logger.changes).contains(Pair(COL_LEVEL, "3")) + assertThat(logger.changes).contains(Pair(COL_SSID, "Test SSID")) + } + @Test + fun logDiffs_activeToCarrierMerged_resetsAllActiveFields() { + val logger = TestLogger() + val activeNetwork = + WifiNetworkModel.Active( + networkId = 5, + isValidated = true, + level = 3, + ssid = "Test SSID" + ) + + WifiNetworkModel.CarrierMerged.logDiffs(prevVal = activeNetwork, logger) + + assertThat(logger.changes).contains(Pair(COL_NETWORK_TYPE, TYPE_CARRIER_MERGED)) + assertThat(logger.changes).contains(Pair(COL_NETWORK_ID, NETWORK_ID_DEFAULT.toString())) + assertThat(logger.changes).contains(Pair(COL_VALIDATED, "false")) + assertThat(logger.changes).contains(Pair(COL_LEVEL, LEVEL_DEFAULT.toString())) + assertThat(logger.changes).contains(Pair(COL_SSID, "null")) + } + + @Test + fun logDiffs_activeChangesLevel_onlyLevelLogged() { + val logger = TestLogger() + val prevActiveNetwork = + WifiNetworkModel.Active( + networkId = 5, + isValidated = true, + level = 3, + ssid = "Test SSID" + ) + val newActiveNetwork = + WifiNetworkModel.Active( + networkId = 5, + isValidated = true, + level = 2, + ssid = "Test SSID" + ) + + newActiveNetwork.logDiffs(prevActiveNetwork, logger) + + assertThat(logger.changes).isEqualTo(listOf(Pair(COL_LEVEL, "2"))) + } + + private class TestLogger : TableRowLogger { + val changes = mutableListOf<Pair<String, String>>() + + override fun logChange(columnName: String, value: String?) { + changes.add(Pair(columnName, value.toString())) + } + + override fun logChange(columnName: String, value: Int) { + changes.add(Pair(columnName, value.toString())) + } + + override fun logChange(columnName: String, value: Boolean) { + changes.add(Pair(columnName, value.toString())) + } + } + companion object { private const val NETWORK_ID = 2 } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt index a64a4bd2e57a..800f3c01c874 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt @@ -29,6 +29,7 @@ import android.net.wifi.WifiManager.TrafficStateCallback import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT @@ -69,6 +70,7 @@ class WifiRepositoryImplTest : SysuiTestCase() { @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var tableLogger: TableLogBuffer @Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var wifiManager: WifiManager private lateinit var executor: Executor @@ -804,6 +806,7 @@ class WifiRepositoryImplTest : SysuiTestCase() { broadcastDispatcher, connectivityManager, logger, + tableLogger, executor, scope, wifiManagerToUse, diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt index 5509a6cac1dd..03fd624a8c1d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt @@ -124,8 +124,11 @@ class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() { { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) }, { foldStateProvider.sendHingeAngleUpdate(10f) }, { foldStateProvider.sendHingeAngleUpdate(90f) }, - { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) }, - { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_CLOSING) }, + { + foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) + // Start closing immediately after we opened, before the animation ended + foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_CLOSING) + }, { foldStateProvider.sendHingeAngleUpdate(60f) }, { foldStateProvider.sendHingeAngleUpdate(10f) }, { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) }, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java index f6fd2cb8f3b1..f68baf5546d7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeFlashlightController.java @@ -16,32 +16,71 @@ package com.android.systemui.utils.leaks; import android.testing.LeakCheck; +import androidx.annotation.VisibleForTesting; + import com.android.systemui.statusbar.policy.FlashlightController; import com.android.systemui.statusbar.policy.FlashlightController.FlashlightListener; +import java.util.ArrayList; +import java.util.List; + public class FakeFlashlightController extends BaseLeakChecker<FlashlightListener> implements FlashlightController { + + private final List<FlashlightListener> callbacks = new ArrayList<>(); + + @VisibleForTesting + public boolean isAvailable; + @VisibleForTesting + public boolean isEnabled; + @VisibleForTesting + public boolean hasFlashlight; + public FakeFlashlightController(LeakCheck test) { super(test, "flashlight"); } + @VisibleForTesting + public void onFlashlightAvailabilityChanged(boolean newValue) { + callbacks.forEach( + flashlightListener -> flashlightListener.onFlashlightAvailabilityChanged(newValue) + ); + } + + @VisibleForTesting + public void onFlashlightError() { + callbacks.forEach(FlashlightListener::onFlashlightError); + } + @Override public boolean hasFlashlight() { - return false; + return hasFlashlight; } @Override public void setFlashlight(boolean newState) { - + callbacks.forEach(flashlightListener -> flashlightListener.onFlashlightChanged(newState)); } @Override public boolean isAvailable() { - return false; + return isAvailable; } @Override public boolean isEnabled() { - return false; + return isEnabled; + } + + @Override + public void addCallback(FlashlightListener listener) { + super.addCallback(listener); + callbacks.add(listener); + } + + @Override + public void removeCallback(FlashlightListener listener) { + super.removeCallback(listener); + callbacks.remove(listener); } } diff --git a/packages/VpnDialogs/res/values-af/strings.xml b/packages/VpnDialogs/res/values-af/strings.xml index b1aedf315034..db3c3558dc69 100644 --- a/packages/VpnDialogs/res/values-af/strings.xml +++ b/packages/VpnDialogs/res/values-af/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Ontkoppel"</string> <string name="open_app" msgid="3717639178595958667">"Maak program oop"</string> <string name="dismiss" msgid="6192859333764711227">"Maak toe"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g> … ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-am/strings.xml b/packages/VpnDialogs/res/values-am/strings.xml index d1fcaa51e34f..d86e043a4c6a 100644 --- a/packages/VpnDialogs/res/values-am/strings.xml +++ b/packages/VpnDialogs/res/values-am/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ግንኙነት አቋርጥ"</string> <string name="open_app" msgid="3717639178595958667">"መተግበሪያን ክፈት"</string> <string name="dismiss" msgid="6192859333764711227">"አሰናብት"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-as/strings.xml b/packages/VpnDialogs/res/values-as/strings.xml index dc99278f3340..736bb8318d99 100644 --- a/packages/VpnDialogs/res/values-as/strings.xml +++ b/packages/VpnDialogs/res/values-as/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"সংযোগ বিচ্ছিন্ন কৰক"</string> <string name="open_app" msgid="3717639178595958667">"এপ্ খোলক"</string> <string name="dismiss" msgid="6192859333764711227">"অগ্ৰাহ্য কৰক"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-az/strings.xml b/packages/VpnDialogs/res/values-az/strings.xml index ca0066f0f622..9b69e3e5d395 100644 --- a/packages/VpnDialogs/res/values-az/strings.xml +++ b/packages/VpnDialogs/res/values-az/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Əlaqəni kəs"</string> <string name="open_app" msgid="3717639178595958667">"Tətbiqi açın"</string> <string name="dismiss" msgid="6192859333764711227">"İmtina edin"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml b/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml index 9f0b4866aeb2..3270744783e6 100644 --- a/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml +++ b/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string> <string name="open_app" msgid="3717639178595958667">"Otvori aplikaciju"</string> <string name="dismiss" msgid="6192859333764711227">"Odbaci"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-be/strings.xml b/packages/VpnDialogs/res/values-be/strings.xml index 3621798767df..54908f6d8ce7 100644 --- a/packages/VpnDialogs/res/values-be/strings.xml +++ b/packages/VpnDialogs/res/values-be/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Адключыцца"</string> <string name="open_app" msgid="3717639178595958667">"Адкрыць праграму"</string> <string name="dismiss" msgid="6192859333764711227">"Адхіліць"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-bg/strings.xml b/packages/VpnDialogs/res/values-bg/strings.xml index df487eeb38c3..734888f6205d 100644 --- a/packages/VpnDialogs/res/values-bg/strings.xml +++ b/packages/VpnDialogs/res/values-bg/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Изключване"</string> <string name="open_app" msgid="3717639178595958667">"Към приложението"</string> <string name="dismiss" msgid="6192859333764711227">"Отхвърляне"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-bn/strings.xml b/packages/VpnDialogs/res/values-bn/strings.xml index 52145d8c7335..f176b2442973 100644 --- a/packages/VpnDialogs/res/values-bn/strings.xml +++ b/packages/VpnDialogs/res/values-bn/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"সংযোগ বিচ্ছিন্ন করুন"</string> <string name="open_app" msgid="3717639178595958667">"অ্যাপটি খুলুন"</string> <string name="dismiss" msgid="6192859333764711227">"খারিজ করুন"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-bs/strings.xml b/packages/VpnDialogs/res/values-bs/strings.xml index 0626b6466ac7..b2f40e22e589 100644 --- a/packages/VpnDialogs/res/values-bs/strings.xml +++ b/packages/VpnDialogs/res/values-bs/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string> <string name="open_app" msgid="3717639178595958667">"Otvori aplikaciju"</string> <string name="dismiss" msgid="6192859333764711227">"Odbaci"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ca/strings.xml b/packages/VpnDialogs/res/values-ca/strings.xml index b8410efec947..aa64abd7247d 100644 --- a/packages/VpnDialogs/res/values-ca/strings.xml +++ b/packages/VpnDialogs/res/values-ca/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Desconnecta"</string> <string name="open_app" msgid="3717639178595958667">"Obre l\'aplicació"</string> <string name="dismiss" msgid="6192859333764711227">"Ignora"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-cs/strings.xml b/packages/VpnDialogs/res/values-cs/strings.xml index b1608f99894a..06589308034e 100644 --- a/packages/VpnDialogs/res/values-cs/strings.xml +++ b/packages/VpnDialogs/res/values-cs/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Odpojit"</string> <string name="open_app" msgid="3717639178595958667">"Do aplikace"</string> <string name="dismiss" msgid="6192859333764711227">"Zavřít"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-da/strings.xml b/packages/VpnDialogs/res/values-da/strings.xml index 2931cb2cd31a..63a32f9c113e 100644 --- a/packages/VpnDialogs/res/values-da/strings.xml +++ b/packages/VpnDialogs/res/values-da/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Fjern tilknytning"</string> <string name="open_app" msgid="3717639178595958667">"Åbn app"</string> <string name="dismiss" msgid="6192859333764711227">"Luk"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-de/strings.xml b/packages/VpnDialogs/res/values-de/strings.xml index 033e5504f785..7397ddb2510c 100644 --- a/packages/VpnDialogs/res/values-de/strings.xml +++ b/packages/VpnDialogs/res/values-de/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Verbindung trennen"</string> <string name="open_app" msgid="3717639178595958667">"App öffnen"</string> <string name="dismiss" msgid="6192859333764711227">"Schließen"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-el/strings.xml b/packages/VpnDialogs/res/values-el/strings.xml index 2c527e8795a5..3d140993541a 100644 --- a/packages/VpnDialogs/res/values-el/strings.xml +++ b/packages/VpnDialogs/res/values-el/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Αποσύνδεση"</string> <string name="open_app" msgid="3717639178595958667">"Άνοιγμα εφαρμογής"</string> <string name="dismiss" msgid="6192859333764711227">"Παράβλεψη"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-es-rUS/strings.xml b/packages/VpnDialogs/res/values-es-rUS/strings.xml index b75e4bf917c1..3a82cb526f15 100644 --- a/packages/VpnDialogs/res/values-es-rUS/strings.xml +++ b/packages/VpnDialogs/res/values-es-rUS/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Desconectar"</string> <string name="open_app" msgid="3717639178595958667">"Abrir app"</string> <string name="dismiss" msgid="6192859333764711227">"Descartar"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-es/strings.xml b/packages/VpnDialogs/res/values-es/strings.xml index d73e2fdc50bc..336ac0570b33 100644 --- a/packages/VpnDialogs/res/values-es/strings.xml +++ b/packages/VpnDialogs/res/values-es/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Desconectar"</string> <string name="open_app" msgid="3717639178595958667">"Abrir aplicación"</string> <string name="dismiss" msgid="6192859333764711227">"Cerrar"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-et/strings.xml b/packages/VpnDialogs/res/values-et/strings.xml index 0e335f2a443f..864b9a428df5 100644 --- a/packages/VpnDialogs/res/values-et/strings.xml +++ b/packages/VpnDialogs/res/values-et/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Katkesta ühendus"</string> <string name="open_app" msgid="3717639178595958667">"Ava rakendus"</string> <string name="dismiss" msgid="6192859333764711227">"Loobu"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-eu/strings.xml b/packages/VpnDialogs/res/values-eu/strings.xml index e7d3e2b23d81..01d80ebf8deb 100644 --- a/packages/VpnDialogs/res/values-eu/strings.xml +++ b/packages/VpnDialogs/res/values-eu/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Deskonektatu"</string> <string name="open_app" msgid="3717639178595958667">"Ireki aplikazioa"</string> <string name="dismiss" msgid="6192859333764711227">"Baztertu"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-fa/strings.xml b/packages/VpnDialogs/res/values-fa/strings.xml index 07f8d1844ec7..47b8735a577f 100644 --- a/packages/VpnDialogs/res/values-fa/strings.xml +++ b/packages/VpnDialogs/res/values-fa/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"قطع اتصال"</string> <string name="open_app" msgid="3717639178595958667">"باز کردن برنامه"</string> <string name="dismiss" msgid="6192859333764711227">"رد کردن"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-fi/strings.xml b/packages/VpnDialogs/res/values-fi/strings.xml index 7e5af3af6d81..a08d66c8b4d7 100644 --- a/packages/VpnDialogs/res/values-fi/strings.xml +++ b/packages/VpnDialogs/res/values-fi/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Katkaise yhteys"</string> <string name="open_app" msgid="3717639178595958667">"Avaa sovellus"</string> <string name="dismiss" msgid="6192859333764711227">"Hylkää"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-fr-rCA/strings.xml b/packages/VpnDialogs/res/values-fr-rCA/strings.xml index 2a1718b60bda..ad450b4c5f39 100644 --- a/packages/VpnDialogs/res/values-fr-rCA/strings.xml +++ b/packages/VpnDialogs/res/values-fr-rCA/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string> <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'application"</string> <string name="dismiss" msgid="6192859333764711227">"Ignorer"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-fr/strings.xml b/packages/VpnDialogs/res/values-fr/strings.xml index ba5f092bf4d3..cdec614d760f 100644 --- a/packages/VpnDialogs/res/values-fr/strings.xml +++ b/packages/VpnDialogs/res/values-fr/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string> <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'application"</string> <string name="dismiss" msgid="6192859333764711227">"Ignorer"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-gl/strings.xml b/packages/VpnDialogs/res/values-gl/strings.xml index b2e3034d2531..5595e15a9a85 100644 --- a/packages/VpnDialogs/res/values-gl/strings.xml +++ b/packages/VpnDialogs/res/values-gl/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Desconectar"</string> <string name="open_app" msgid="3717639178595958667">"Abrir aplicación"</string> <string name="dismiss" msgid="6192859333764711227">"Pechar"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-gu/strings.xml b/packages/VpnDialogs/res/values-gu/strings.xml index 6e9bd320aa84..516d51c409f0 100644 --- a/packages/VpnDialogs/res/values-gu/strings.xml +++ b/packages/VpnDialogs/res/values-gu/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ડિસ્કનેક્ટ કરો"</string> <string name="open_app" msgid="3717639178595958667">"ઍપ ખોલો"</string> <string name="dismiss" msgid="6192859333764711227">"છોડી દો"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-hi/strings.xml b/packages/VpnDialogs/res/values-hi/strings.xml index 3e65649c6f49..ad0cc0b128aa 100644 --- a/packages/VpnDialogs/res/values-hi/strings.xml +++ b/packages/VpnDialogs/res/values-hi/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"डिसकनेक्ट करें"</string> <string name="open_app" msgid="3717639178595958667">"ऐप खोलें"</string> <string name="dismiss" msgid="6192859333764711227">"खारिज करें"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-hr/strings.xml b/packages/VpnDialogs/res/values-hr/strings.xml index dddaa5837b33..ec1868870ab6 100644 --- a/packages/VpnDialogs/res/values-hr/strings.xml +++ b/packages/VpnDialogs/res/values-hr/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string> <string name="open_app" msgid="3717639178595958667">"Otvori aplikaciju"</string> <string name="dismiss" msgid="6192859333764711227">"Odbaci"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-hu/strings.xml b/packages/VpnDialogs/res/values-hu/strings.xml index a719ef983d77..0ce41ce82e4a 100644 --- a/packages/VpnDialogs/res/values-hu/strings.xml +++ b/packages/VpnDialogs/res/values-hu/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Kapcsolat bontása"</string> <string name="open_app" msgid="3717639178595958667">"Alkalmazás indítása"</string> <string name="dismiss" msgid="6192859333764711227">"Bezárás"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-hy/strings.xml b/packages/VpnDialogs/res/values-hy/strings.xml index b67f79e8087d..b699902353ce 100644 --- a/packages/VpnDialogs/res/values-hy/strings.xml +++ b/packages/VpnDialogs/res/values-hy/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Անջատել"</string> <string name="open_app" msgid="3717639178595958667">"Բացել հավելվածը"</string> <string name="dismiss" msgid="6192859333764711227">"Փակել"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-in/strings.xml b/packages/VpnDialogs/res/values-in/strings.xml index 20da563633d0..342f403ef09f 100644 --- a/packages/VpnDialogs/res/values-in/strings.xml +++ b/packages/VpnDialogs/res/values-in/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Putuskan koneksi"</string> <string name="open_app" msgid="3717639178595958667">"Buka aplikasi"</string> <string name="dismiss" msgid="6192859333764711227">"Tutup"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-is/strings.xml b/packages/VpnDialogs/res/values-is/strings.xml index ab476b2a2e56..a52292ce2bdf 100644 --- a/packages/VpnDialogs/res/values-is/strings.xml +++ b/packages/VpnDialogs/res/values-is/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Aftengja"</string> <string name="open_app" msgid="3717639178595958667">"Opna forrit"</string> <string name="dismiss" msgid="6192859333764711227">"Hunsa"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-it/strings.xml b/packages/VpnDialogs/res/values-it/strings.xml index 19347bff4516..7773c9e4813a 100644 --- a/packages/VpnDialogs/res/values-it/strings.xml +++ b/packages/VpnDialogs/res/values-it/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Disconnetti"</string> <string name="open_app" msgid="3717639178595958667">"Apri app"</string> <string name="dismiss" msgid="6192859333764711227">"Ignora"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ka/strings.xml b/packages/VpnDialogs/res/values-ka/strings.xml index d63b4162c25b..5c4c8158044b 100644 --- a/packages/VpnDialogs/res/values-ka/strings.xml +++ b/packages/VpnDialogs/res/values-ka/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"კავშირის გაწყვეტა"</string> <string name="open_app" msgid="3717639178595958667">"გახსენით აპი"</string> <string name="dismiss" msgid="6192859333764711227">"დახურვა"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-kk/strings.xml b/packages/VpnDialogs/res/values-kk/strings.xml index b109d91ed652..a519e4c068ae 100644 --- a/packages/VpnDialogs/res/values-kk/strings.xml +++ b/packages/VpnDialogs/res/values-kk/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Ажырату"</string> <string name="open_app" msgid="3717639178595958667">"Қолданбаны ашу"</string> <string name="dismiss" msgid="6192859333764711227">"Жабу"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-km/strings.xml b/packages/VpnDialogs/res/values-km/strings.xml index 7e4e9b66187d..d93c6943861e 100644 --- a/packages/VpnDialogs/res/values-km/strings.xml +++ b/packages/VpnDialogs/res/values-km/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ផ្ដាច់"</string> <string name="open_app" msgid="3717639178595958667">"បើកកម្មវិធី"</string> <string name="dismiss" msgid="6192859333764711227">"ច្រានចោល"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-kn/strings.xml b/packages/VpnDialogs/res/values-kn/strings.xml index 864efd55ad26..4f8d90b20405 100644 --- a/packages/VpnDialogs/res/values-kn/strings.xml +++ b/packages/VpnDialogs/res/values-kn/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸು"</string> <string name="open_app" msgid="3717639178595958667">"ಅಪ್ಲಿಕೇಶನ್ ತೆರೆಯಿರಿ"</string> <string name="dismiss" msgid="6192859333764711227">"ವಜಾಗೊಳಿಸಿ"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ko/strings.xml b/packages/VpnDialogs/res/values-ko/strings.xml index 15aa323cd0e7..ebadad7a5b0e 100644 --- a/packages/VpnDialogs/res/values-ko/strings.xml +++ b/packages/VpnDialogs/res/values-ko/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"연결 끊기"</string> <string name="open_app" msgid="3717639178595958667">"앱 열기"</string> <string name="dismiss" msgid="6192859333764711227">"닫기"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>…(<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g>(<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ky/strings.xml b/packages/VpnDialogs/res/values-ky/strings.xml index 077398445648..2087b62a9eb6 100644 --- a/packages/VpnDialogs/res/values-ky/strings.xml +++ b/packages/VpnDialogs/res/values-ky/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Ажыратуу"</string> <string name="open_app" msgid="3717639178595958667">"Колдонмону ачуу"</string> <string name="dismiss" msgid="6192859333764711227">"Четке кагуу"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-lo/strings.xml b/packages/VpnDialogs/res/values-lo/strings.xml index 747e1f4ac068..4c36b71a2a7c 100644 --- a/packages/VpnDialogs/res/values-lo/strings.xml +++ b/packages/VpnDialogs/res/values-lo/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ຕັດການເຊື່ອມຕໍ່"</string> <string name="open_app" msgid="3717639178595958667">"ເປີດແອັບ"</string> <string name="dismiss" msgid="6192859333764711227">"ປິດໄວ້"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-lt/strings.xml b/packages/VpnDialogs/res/values-lt/strings.xml index 1d9d5700d85e..d8783d232ac9 100644 --- a/packages/VpnDialogs/res/values-lt/strings.xml +++ b/packages/VpnDialogs/res/values-lt/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Atsijungti"</string> <string name="open_app" msgid="3717639178595958667">"Atidaryti programą"</string> <string name="dismiss" msgid="6192859333764711227">"Atsisakyti"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-lv/strings.xml b/packages/VpnDialogs/res/values-lv/strings.xml index e3a2db892f74..7e8ecc1fe11c 100644 --- a/packages/VpnDialogs/res/values-lv/strings.xml +++ b/packages/VpnDialogs/res/values-lv/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Pārtraukt savienojumu"</string> <string name="open_app" msgid="3717639178595958667">"Atvērt lietotni"</string> <string name="dismiss" msgid="6192859333764711227">"Nerādīt"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-mk/strings.xml b/packages/VpnDialogs/res/values-mk/strings.xml index 867e6d1295e7..ec692ab02249 100644 --- a/packages/VpnDialogs/res/values-mk/strings.xml +++ b/packages/VpnDialogs/res/values-mk/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Прекини врска"</string> <string name="open_app" msgid="3717639178595958667">"Отвори ја апликацијата"</string> <string name="dismiss" msgid="6192859333764711227">"Отфрли"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ml/strings.xml b/packages/VpnDialogs/res/values-ml/strings.xml index 2c5b048f0d54..a98bcdcb1059 100644 --- a/packages/VpnDialogs/res/values-ml/strings.xml +++ b/packages/VpnDialogs/res/values-ml/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"വിച്ഛേദിക്കുക"</string> <string name="open_app" msgid="3717639178595958667">"ആപ്പ് തുറക്കുക"</string> <string name="dismiss" msgid="6192859333764711227">"നിരസിക്കുക"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-mn/strings.xml b/packages/VpnDialogs/res/values-mn/strings.xml index a0d841887a7c..8eb3289454af 100644 --- a/packages/VpnDialogs/res/values-mn/strings.xml +++ b/packages/VpnDialogs/res/values-mn/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Салгах"</string> <string name="open_app" msgid="3717639178595958667">"Апп нээх"</string> <string name="dismiss" msgid="6192859333764711227">"Хаах"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-mr/strings.xml b/packages/VpnDialogs/res/values-mr/strings.xml index 6aeb9e710d20..cccf3695a537 100644 --- a/packages/VpnDialogs/res/values-mr/strings.xml +++ b/packages/VpnDialogs/res/values-mr/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"डिस्कनेक्ट करा"</string> <string name="open_app" msgid="3717639178595958667">"अॅप उघडा"</string> <string name="dismiss" msgid="6192859333764711227">"डिसमिस करा"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ms/strings.xml b/packages/VpnDialogs/res/values-ms/strings.xml index fe2f43337f46..ad42abb3e3d7 100644 --- a/packages/VpnDialogs/res/values-ms/strings.xml +++ b/packages/VpnDialogs/res/values-ms/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Putuskan sambungan"</string> <string name="open_app" msgid="3717639178595958667">"Buka apl"</string> <string name="dismiss" msgid="6192859333764711227">"Ketepikan"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-my/strings.xml b/packages/VpnDialogs/res/values-my/strings.xml index 02bb68dfb67c..bc212a265f48 100644 --- a/packages/VpnDialogs/res/values-my/strings.xml +++ b/packages/VpnDialogs/res/values-my/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ချိတ်ဆက်မှုဖြုတ်ရန်"</string> <string name="open_app" msgid="3717639178595958667">"အက်ပ်ကို ဖွင့်ရန်"</string> <string name="dismiss" msgid="6192859333764711227">"ပယ်ရန်"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-nb/strings.xml b/packages/VpnDialogs/res/values-nb/strings.xml index 9904745ce104..bca01d0dbeba 100644 --- a/packages/VpnDialogs/res/values-nb/strings.xml +++ b/packages/VpnDialogs/res/values-nb/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Koble fra"</string> <string name="open_app" msgid="3717639178595958667">"Åpne appen"</string> <string name="dismiss" msgid="6192859333764711227">"Lukk"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ne/strings.xml b/packages/VpnDialogs/res/values-ne/strings.xml index 1453dfbedb41..675a76dc6c02 100644 --- a/packages/VpnDialogs/res/values-ne/strings.xml +++ b/packages/VpnDialogs/res/values-ne/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"डिस्कनेक्ट गर्नुहोस्"</string> <string name="open_app" msgid="3717639178595958667">"एप खोल्नुहोस्"</string> <string name="dismiss" msgid="6192859333764711227">"खारेज गर्नुहोस्"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-nl/strings.xml b/packages/VpnDialogs/res/values-nl/strings.xml index 4223cf44394d..80e7f1b12b07 100644 --- a/packages/VpnDialogs/res/values-nl/strings.xml +++ b/packages/VpnDialogs/res/values-nl/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Verbinding verbreken"</string> <string name="open_app" msgid="3717639178595958667">"App openen"</string> <string name="dismiss" msgid="6192859333764711227">"Sluiten"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-or/strings.xml b/packages/VpnDialogs/res/values-or/strings.xml index 2714af3183ee..2f5a3dd06626 100644 --- a/packages/VpnDialogs/res/values-or/strings.xml +++ b/packages/VpnDialogs/res/values-or/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ବିଚ୍ଛିନ୍ନ କରନ୍ତୁ"</string> <string name="open_app" msgid="3717639178595958667">"ଆପ୍ ଖୋଲନ୍ତୁ"</string> <string name="dismiss" msgid="6192859333764711227">"ଖାରଜ କରନ୍ତୁ"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-pa/strings.xml b/packages/VpnDialogs/res/values-pa/strings.xml index 969d5e24ba37..427cf8682b23 100644 --- a/packages/VpnDialogs/res/values-pa/strings.xml +++ b/packages/VpnDialogs/res/values-pa/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string> <string name="open_app" msgid="3717639178595958667">"ਐਪ ਖੋਲ੍ਹੋ"</string> <string name="dismiss" msgid="6192859333764711227">"ਖਾਰਜ ਕਰੋ"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-pl/strings.xml b/packages/VpnDialogs/res/values-pl/strings.xml index 199988fc0aaf..1bd89bb43dd3 100644 --- a/packages/VpnDialogs/res/values-pl/strings.xml +++ b/packages/VpnDialogs/res/values-pl/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Rozłącz"</string> <string name="open_app" msgid="3717639178595958667">"Otwórz aplikację"</string> <string name="dismiss" msgid="6192859333764711227">"Zamknij"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-pt-rBR/strings.xml b/packages/VpnDialogs/res/values-pt-rBR/strings.xml index 8718d76687f8..53d65af4efd9 100644 --- a/packages/VpnDialogs/res/values-pt-rBR/strings.xml +++ b/packages/VpnDialogs/res/values-pt-rBR/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Desconectar"</string> <string name="open_app" msgid="3717639178595958667">"Abrir app"</string> <string name="dismiss" msgid="6192859333764711227">"Dispensar"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-pt/strings.xml b/packages/VpnDialogs/res/values-pt/strings.xml index 8718d76687f8..53d65af4efd9 100644 --- a/packages/VpnDialogs/res/values-pt/strings.xml +++ b/packages/VpnDialogs/res/values-pt/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Desconectar"</string> <string name="open_app" msgid="3717639178595958667">"Abrir app"</string> <string name="dismiss" msgid="6192859333764711227">"Dispensar"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ro/strings.xml b/packages/VpnDialogs/res/values-ro/strings.xml index 1b18afa45a1d..f45609beba66 100644 --- a/packages/VpnDialogs/res/values-ro/strings.xml +++ b/packages/VpnDialogs/res/values-ro/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Deconectează"</string> <string name="open_app" msgid="3717639178595958667">"Deschide aplicația"</string> <string name="dismiss" msgid="6192859333764711227">"Închide"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ru/strings.xml b/packages/VpnDialogs/res/values-ru/strings.xml index 06d7e02403df..2e346d348072 100644 --- a/packages/VpnDialogs/res/values-ru/strings.xml +++ b/packages/VpnDialogs/res/values-ru/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Разъединить"</string> <string name="open_app" msgid="3717639178595958667">"Открыть приложение"</string> <string name="dismiss" msgid="6192859333764711227">"Закрыть"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-si/strings.xml b/packages/VpnDialogs/res/values-si/strings.xml index 23c8c227d63f..fa5a70f0c3bd 100644 --- a/packages/VpnDialogs/res/values-si/strings.xml +++ b/packages/VpnDialogs/res/values-si/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"විසන්ධි කරන්න"</string> <string name="open_app" msgid="3717639178595958667">"යෙදුම විවෘත කරන්න"</string> <string name="dismiss" msgid="6192859333764711227">"ඉවතලන්න"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-sk/strings.xml b/packages/VpnDialogs/res/values-sk/strings.xml index 22f390c44f1d..755abb2860c6 100644 --- a/packages/VpnDialogs/res/values-sk/strings.xml +++ b/packages/VpnDialogs/res/values-sk/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Odpojiť"</string> <string name="open_app" msgid="3717639178595958667">"Otvoriť aplikáciu"</string> <string name="dismiss" msgid="6192859333764711227">"Zavrieť"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-sl/strings.xml b/packages/VpnDialogs/res/values-sl/strings.xml index 2f35e34db6d6..b473ce0a3160 100644 --- a/packages/VpnDialogs/res/values-sl/strings.xml +++ b/packages/VpnDialogs/res/values-sl/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Prekini povezavo"</string> <string name="open_app" msgid="3717639178595958667">"Odpri aplikacijo"</string> <string name="dismiss" msgid="6192859333764711227">"Opusti"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g> … (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-sq/strings.xml b/packages/VpnDialogs/res/values-sq/strings.xml index 174b2782d0d4..ad9f66e65158 100644 --- a/packages/VpnDialogs/res/values-sq/strings.xml +++ b/packages/VpnDialogs/res/values-sq/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Shkëputu"</string> <string name="open_app" msgid="3717639178595958667">"Hap aplikacionin"</string> <string name="dismiss" msgid="6192859333764711227">"Hiq"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-sr/strings.xml b/packages/VpnDialogs/res/values-sr/strings.xml index 019a5b4428f2..eaa0aeffcb3e 100644 --- a/packages/VpnDialogs/res/values-sr/strings.xml +++ b/packages/VpnDialogs/res/values-sr/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Прекини везу"</string> <string name="open_app" msgid="3717639178595958667">"Отвори апликацију"</string> <string name="dismiss" msgid="6192859333764711227">"Одбаци"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-sv/strings.xml b/packages/VpnDialogs/res/values-sv/strings.xml index 5e0aec372c28..175ebbada1eb 100644 --- a/packages/VpnDialogs/res/values-sv/strings.xml +++ b/packages/VpnDialogs/res/values-sv/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Koppla från"</string> <string name="open_app" msgid="3717639178595958667">"Öppna appen"</string> <string name="dismiss" msgid="6192859333764711227">"Ignorera"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-sw/strings.xml b/packages/VpnDialogs/res/values-sw/strings.xml index 1dfbe7aacde2..66c2899009fd 100644 --- a/packages/VpnDialogs/res/values-sw/strings.xml +++ b/packages/VpnDialogs/res/values-sw/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Tenganisha"</string> <string name="open_app" msgid="3717639178595958667">"Fungua programu"</string> <string name="dismiss" msgid="6192859333764711227">"Ondoa"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ta/strings.xml b/packages/VpnDialogs/res/values-ta/strings.xml index 87f64dea3031..31602a6a9152 100644 --- a/packages/VpnDialogs/res/values-ta/strings.xml +++ b/packages/VpnDialogs/res/values-ta/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"தொடர்பைத் துண்டி"</string> <string name="open_app" msgid="3717639178595958667">"பயன்பாட்டைத் திற"</string> <string name="dismiss" msgid="6192859333764711227">"நிராகரி"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-te/strings.xml b/packages/VpnDialogs/res/values-te/strings.xml index fcf54bc3fcdd..685dd26de30d 100644 --- a/packages/VpnDialogs/res/values-te/strings.xml +++ b/packages/VpnDialogs/res/values-te/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"డిస్కనెక్ట్ చేయి"</string> <string name="open_app" msgid="3717639178595958667">"యాప్ని తెరవండి"</string> <string name="dismiss" msgid="6192859333764711227">"తీసివేయండి"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-tl/strings.xml b/packages/VpnDialogs/res/values-tl/strings.xml index bb099e7f23f5..0b4a10625697 100644 --- a/packages/VpnDialogs/res/values-tl/strings.xml +++ b/packages/VpnDialogs/res/values-tl/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Idiskonekta"</string> <string name="open_app" msgid="3717639178595958667">"Buksan ang app"</string> <string name="dismiss" msgid="6192859333764711227">"I-dismiss"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-tr/strings.xml b/packages/VpnDialogs/res/values-tr/strings.xml index 8204234d3e67..e3606effa3fc 100644 --- a/packages/VpnDialogs/res/values-tr/strings.xml +++ b/packages/VpnDialogs/res/values-tr/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Bağlantıyı kes"</string> <string name="open_app" msgid="3717639178595958667">"Uygulamayı aç"</string> <string name="dismiss" msgid="6192859333764711227">"Kapat"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-uk/strings.xml b/packages/VpnDialogs/res/values-uk/strings.xml index 3890096bda73..1dd0e8aa6364 100644 --- a/packages/VpnDialogs/res/values-uk/strings.xml +++ b/packages/VpnDialogs/res/values-uk/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Від’єднати"</string> <string name="open_app" msgid="3717639178595958667">"Відкрити додаток"</string> <string name="dismiss" msgid="6192859333764711227">"Закрити"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-ur/strings.xml b/packages/VpnDialogs/res/values-ur/strings.xml index 7fa828a205b9..803f0427c78b 100644 --- a/packages/VpnDialogs/res/values-ur/strings.xml +++ b/packages/VpnDialogs/res/values-ur/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"منقطع کریں"</string> <string name="open_app" msgid="3717639178595958667">"ایپ کھولیں"</string> <string name="dismiss" msgid="6192859333764711227">"برخاست کریں"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-uz/strings.xml b/packages/VpnDialogs/res/values-uz/strings.xml index 80dcf945f9a2..a54fa0834ae9 100644 --- a/packages/VpnDialogs/res/values-uz/strings.xml +++ b/packages/VpnDialogs/res/values-uz/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Aloqani uzish"</string> <string name="open_app" msgid="3717639178595958667">"Ilovani ochish"</string> <string name="dismiss" msgid="6192859333764711227">"Yopish"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-vi/strings.xml b/packages/VpnDialogs/res/values-vi/strings.xml index 7d8cc8622751..6ce9f393f1cc 100644 --- a/packages/VpnDialogs/res/values-vi/strings.xml +++ b/packages/VpnDialogs/res/values-vi/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Ngắt kết nối"</string> <string name="open_app" msgid="3717639178595958667">"Mở ứng dụng"</string> <string name="dismiss" msgid="6192859333764711227">"Loại bỏ"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-zh-rCN/strings.xml b/packages/VpnDialogs/res/values-zh-rCN/strings.xml index 1d8adbbdafff..38a2e8de6161 100644 --- a/packages/VpnDialogs/res/values-zh-rCN/strings.xml +++ b/packages/VpnDialogs/res/values-zh-rCN/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"断开连接"</string> <string name="open_app" msgid="3717639178595958667">"打开应用"</string> <string name="dismiss" msgid="6192859333764711227">"关闭"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>…(<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-zh-rHK/strings.xml b/packages/VpnDialogs/res/values-zh-rHK/strings.xml index a0d6ee081f55..f3abf3cd89a2 100644 --- a/packages/VpnDialogs/res/values-zh-rHK/strings.xml +++ b/packages/VpnDialogs/res/values-zh-rHK/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"中斷連線"</string> <string name="open_app" msgid="3717639178595958667">"開啟應用程式"</string> <string name="dismiss" msgid="6192859333764711227">"關閉"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-zh-rTW/strings.xml b/packages/VpnDialogs/res/values-zh-rTW/strings.xml index 948bc5946eeb..3f1336be9184 100644 --- a/packages/VpnDialogs/res/values-zh-rTW/strings.xml +++ b/packages/VpnDialogs/res/values-zh-rTW/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"中斷連線"</string> <string name="open_app" msgid="3717639178595958667">"開啟應用程式"</string> <string name="dismiss" msgid="6192859333764711227">"關閉"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… (<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> (<xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/packages/VpnDialogs/res/values-zu/strings.xml b/packages/VpnDialogs/res/values-zu/strings.xml index 875873f6f22d..563ed0f5beb4 100644 --- a/packages/VpnDialogs/res/values-zu/strings.xml +++ b/packages/VpnDialogs/res/values-zu/strings.xml @@ -34,8 +34,6 @@ <string name="disconnect" msgid="971412338304200056">"Ayixhumekile kwi-inthanethi"</string> <string name="open_app" msgid="3717639178595958667">"Vula uhlelo lokusebenza"</string> <string name="dismiss" msgid="6192859333764711227">"Cashisa"</string> - <!-- no translation found for sanitized_vpn_label_with_ellipsis (7014327474633422235) --> - <skip /> - <!-- no translation found for sanitized_vpn_label (1877415015009794766) --> - <skip /> + <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string> + <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string> </resources> diff --git a/services/OWNERS b/services/OWNERS index 495c0737e599..eace9060277d 100644 --- a/services/OWNERS +++ b/services/OWNERS @@ -3,7 +3,7 @@ per-file Android.bp = file:platform/build/soong:/OWNERS #{LAST_RESORT_SUGGESTION # art-team@ manages the system server profile per-file art-profile* = calin@google.com, ngeoffray@google.com, vmarko@google.com -per-file java/com/android/server/* = toddke@google.com,patb@google.com +per-file java/com/android/server/* = patb@google.com #{LAST_RESORT_SUGGESTION} per-file tests/servicestests/src/com/android/server/systemconfig/* = patb@google.com per-file proguard.flags = jdduke@google.com diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 3cfae605caee..8baae53a444c 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -35,6 +35,7 @@ import android.app.AlarmManager; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.AppOpsManagerInternal; +import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.IServiceConnection; import android.app.KeyguardManager; @@ -257,6 +258,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku private boolean mIsProviderInfoPersisted; private boolean mIsCombinedBroadcastEnabled; + // Mark widget lifecycle broadcasts as 'interactive' + private Bundle mInteractiveBroadcast; + AppWidgetServiceImpl(Context context) { mContext = context; } @@ -286,6 +290,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Slog.d(TAG, "App widget provider info will not be persisted on this device"); } + BroadcastOptions opts = BroadcastOptions.makeBasic(); + opts.setBackgroundActivityStartsAllowed(false); + opts.setInteractive(true); + mInteractiveBroadcast = opts.toBundle(); + computeMaximumWidgetBitmapMemory(); registerBroadcastReceiver(); registerOnCrossProfileProvidersChangedListener(); @@ -2379,33 +2388,40 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_ENABLE_AND_UPDATE); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); intent.setComponent(p.id.componentName); - sendBroadcastAsUser(intent, p.id.getProfile()); + // Placing a widget is something users expect to be UX-responsive, so mark this + // broadcast as interactive + sendBroadcastAsUser(intent, p.id.getProfile(), true); } private void sendEnableIntentLocked(Provider p) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_ENABLED); intent.setComponent(p.id.componentName); - sendBroadcastAsUser(intent, p.id.getProfile()); + // Enabling the widget is something users expect to be UX-responsive, so mark this + // broadcast as interactive + sendBroadcastAsUser(intent, p.id.getProfile(), true); } private void sendUpdateIntentLocked(Provider provider, int[] appWidgetIds) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); intent.setComponent(provider.id.componentName); - sendBroadcastAsUser(intent, provider.id.getProfile()); + // Periodic background widget update heartbeats are not an interactive use case + sendBroadcastAsUser(intent, provider.id.getProfile(), false); } private void sendDeletedIntentLocked(Widget widget) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DELETED); intent.setComponent(widget.provider.id.componentName); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget.appWidgetId); - sendBroadcastAsUser(intent, widget.provider.id.getProfile()); + // Cleanup after deletion isn't an interactive UX case + sendBroadcastAsUser(intent, widget.provider.id.getProfile(), false); } private void sendDisabledIntentLocked(Provider provider) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DISABLED); intent.setComponent(provider.id.componentName); - sendBroadcastAsUser(intent, provider.id.getProfile()); + // Cleanup after disable isn't an interactive UX case + sendBroadcastAsUser(intent, provider.id.getProfile(), false); } public void sendOptionsChangedIntentLocked(Widget widget) { @@ -2413,7 +2429,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku intent.setComponent(widget.provider.id.componentName); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget.appWidgetId); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, widget.options); - sendBroadcastAsUser(intent, widget.provider.id.getProfile()); + // The user's changed the options, so seeing them take effect promptly is + // an interactive UX expectation + sendBroadcastAsUser(intent, widget.provider.id.getProfile(), true); } @GuardedBy("mLock") @@ -3666,10 +3684,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku return null; } - private void sendBroadcastAsUser(Intent intent, UserHandle userHandle) { + /** + * Sends a widget lifecycle broadcast within the specified user. If {@code isInteractive} + * is specified as {@code true}, the broadcast dispatch mechanism will be told that it + * is related to a UX flow with user-visible expectations about timely dispatch. This + * should only be used for broadcast flows that do have such expectations. + */ + private void sendBroadcastAsUser(Intent intent, UserHandle userHandle, boolean isInteractive) { final long identity = Binder.clearCallingIdentity(); try { - mContext.sendBroadcastAsUser(intent, userHandle); + mContext.sendBroadcastAsUser(intent, userHandle, null, + isInteractive ? mInteractiveBroadcast : null); } finally { Binder.restoreCallingIdentity(identity); } @@ -5008,18 +5033,20 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku private void sendWidgetRestoreBroadcastLocked(String action, Provider provider, Host host, int[] oldIds, int[] newIds, UserHandle userHandle) { + // Users expect restore to emplace widgets properly ASAP, so flag these as + // being interactive broadcast dispatches Intent intent = new Intent(action); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS, oldIds); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, newIds); if (provider != null) { intent.setComponent(provider.id.componentName); - sendBroadcastAsUser(intent, userHandle); + sendBroadcastAsUser(intent, userHandle, true); } if (host != null) { intent.setComponent(null); intent.setPackage(host.id.packageName); intent.putExtra(AppWidgetManager.EXTRA_HOST_ID, host.id.hostId); - sendBroadcastAsUser(intent, userHandle); + sendBroadcastAsUser(intent, userHandle, true); } } diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java index 0fe90b14c9bb..f5d68362c70a 100644 --- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java +++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java @@ -9,7 +9,7 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_MANIFEST import android.app.ApplicationThreadConstants; import android.app.IBackupAgent; -import android.app.backup.BackupManager; +import android.app.backup.BackupAnnotations; import android.app.backup.FullBackup; import android.app.backup.FullBackupDataOutput; import android.app.backup.IBackupCallback; @@ -148,7 +148,7 @@ public class KeyValueAdbBackupEngine { try { return mBackupManagerService.bindToAgentSynchronous(targetApp, ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL, - BackupManager.OperationType.BACKUP); + BackupAnnotations.BackupDestination.CLOUD); } catch (SecurityException e) { Slog.e(TAG, "error in binding to agent for package " + targetApp.packageName + ". " + e); diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 4cf63b35eb92..ce3e6289d40e 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -46,8 +46,8 @@ import android.app.IActivityManager; import android.app.IBackupAgent; import android.app.PendingIntent; import android.app.backup.BackupAgent; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.BackupManager; -import android.app.backup.BackupManager.OperationType; import android.app.backup.BackupManagerMonitor; import android.app.backup.FullBackup; import android.app.backup.IBackupManager; @@ -405,7 +405,7 @@ public class UserBackupManagerService { private long mAncestralToken = 0; private long mCurrentToken = 0; @Nullable private File mAncestralSerialNumberFile; - @OperationType private volatile long mAncestralOperationType; + @BackupDestination private volatile long mAncestralBackupDestination; private final ContentObserver mSetupObserver; private final BroadcastReceiver mRunInitReceiver; @@ -550,7 +550,7 @@ public class UserBackupManagerService { mActivityManager = ActivityManager.getService(); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mScheduledBackupEligibility = getEligibilityRules(mPackageManager, userId, - OperationType.BACKUP); + BackupDestination.CLOUD); mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); @@ -844,8 +844,8 @@ public class UserBackupManagerService { mAncestralToken = ancestralToken; } - public void setAncestralOperationType(@OperationType int operationType) { - mAncestralOperationType = operationType; + public void setAncestralBackupDestination(@BackupDestination int backupDestination) { + mAncestralBackupDestination = backupDestination; } public long getCurrentToken() { @@ -1619,14 +1619,14 @@ public class UserBackupManagerService { /** Fires off a backup agent, blocking until it attaches or times out. */ @Nullable public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode, - @OperationType int operationType) { + @BackupDestination int backupDestination) { IBackupAgent agent = null; synchronized (mAgentConnectLock) { mConnecting = true; mConnectedAgent = null; try { if (mActivityManager.bindBackupAgent(app.packageName, mode, mUserId, - operationType)) { + backupDestination)) { Slog.d(TAG, addUserIdToLogMessage(mUserId, "awaiting agent for " + app)); // success; wait for the agent to arrive @@ -1776,8 +1776,9 @@ public class UserBackupManagerService { } private BackupEligibilityRules getEligibilityRulesForRestoreAtInstall(long restoreToken) { - if (mAncestralOperationType == OperationType.MIGRATION && restoreToken == mAncestralToken) { - return getEligibilityRulesForOperation(OperationType.MIGRATION); + if (mAncestralBackupDestination == BackupDestination.DEVICE_TRANSFER + && restoreToken == mAncestralToken) { + return getEligibilityRulesForOperation(BackupDestination.DEVICE_TRANSFER); } else { // If we're not using the ancestral data set, it means we're restoring from a backup // that happened on this device. @@ -1856,14 +1857,14 @@ public class UserBackupManagerService { final TransportConnection transportConnection; final String transportDirName; - int operationType; + int backupDestination; try { transportDirName = mTransportManager.getTransportDirName( mTransportManager.getCurrentTransportName()); transportConnection = mTransportManager.getCurrentTransportClientOrThrow("BMS.requestBackup()"); - operationType = getOperationTypeFromTransport(transportConnection); + backupDestination = getBackupDestinationFromTransport(transportConnection); } catch (TransportNotRegisteredException | TransportNotAvailableException | RemoteException e) { BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED); @@ -1876,7 +1877,7 @@ public class UserBackupManagerService { OnTaskFinishedListener listener = caller -> mTransportManager.disposeOfTransportClient(transportConnection, caller); BackupEligibilityRules backupEligibilityRules = getEligibilityRulesForOperation( - operationType); + backupDestination); Message msg = mBackupHandler.obtainMessage(MSG_REQUEST_BACKUP); msg.obj = getRequestBackupParams(packages, observer, monitor, flags, backupEligibilityRules, @@ -2373,7 +2374,7 @@ public class UserBackupManagerService { /* monitor */ null, /* userInitiated */ false, "BMS.beginFullBackup()", - getEligibilityRulesForOperation(OperationType.BACKUP)); + getEligibilityRulesForOperation(BackupDestination.CLOUD)); } catch (IllegalStateException e) { Slog.w(TAG, "Failed to start backup", e); runBackup = false; @@ -2835,7 +2836,7 @@ public class UserBackupManagerService { Slog.i(TAG, addUserIdToLogMessage(mUserId, "Beginning adb backup...")); BackupEligibilityRules eligibilityRules = getEligibilityRulesForOperation( - OperationType.ADB_BACKUP); + BackupDestination.ADB_BACKUP); AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs, includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue, pkgList, eligibilityRules); @@ -2924,7 +2925,7 @@ public class UserBackupManagerService { /* monitor */ null, /* userInitiated */ false, "BMS.fullTransportBackup()", - getEligibilityRulesForOperation(OperationType.BACKUP)); + getEligibilityRulesForOperation(BackupDestination.CLOUD)); // Acquiring wakelock for PerformFullTransportBackupTask before its start. mWakelock.acquire(); (new Thread(task, "full-transport-master")).start(); @@ -3917,12 +3918,12 @@ public class UserBackupManagerService { } } - int operationType; + int backupDestination; TransportConnection transportConnection = null; try { transportConnection = mTransportManager.getTransportClientOrThrow( transport, /* caller */"BMS.beginRestoreSession"); - operationType = getOperationTypeFromTransport(transportConnection); + backupDestination = getBackupDestinationFromTransport(transportConnection); } catch (TransportNotAvailableException | TransportNotRegisteredException | RemoteException e) { Slog.w(TAG, "Failed to get operation type from transport: " + e); @@ -3951,7 +3952,7 @@ public class UserBackupManagerService { return null; } mActiveRestoreSession = new ActiveRestoreSession(this, packageName, transport, - getEligibilityRulesForOperation(operationType)); + getEligibilityRulesForOperation(backupDestination)); mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, mAgentTimeoutParameters.getRestoreSessionTimeoutMillis()); } @@ -4037,14 +4038,14 @@ public class UserBackupManagerService { } public BackupEligibilityRules getEligibilityRulesForOperation( - @OperationType int operationType) { - return getEligibilityRules(mPackageManager, mUserId, operationType); + @BackupDestination int backupDestination) { + return getEligibilityRules(mPackageManager, mUserId, backupDestination); } private static BackupEligibilityRules getEligibilityRules(PackageManager packageManager, - int userId, @OperationType int operationType) { + int userId, @BackupDestination int backupDestination) { return new BackupEligibilityRules(packageManager, - LocalServices.getService(PackageManagerInternal.class), userId, operationType); + LocalServices.getService(PackageManagerInternal.class), userId, backupDestination); } /** Prints service state for 'dumpsys backup'. */ @@ -4200,21 +4201,22 @@ public class UserBackupManagerService { } @VisibleForTesting - @OperationType int getOperationTypeFromTransport(TransportConnection transportConnection) + @BackupDestination int getBackupDestinationFromTransport( + TransportConnection transportConnection) throws TransportNotAvailableException, RemoteException { if (!shouldUseNewBackupEligibilityRules()) { // Return the default to stick to the legacy behaviour. - return OperationType.BACKUP; + return BackupDestination.CLOUD; } final long oldCallingId = Binder.clearCallingIdentity(); try { BackupTransportClient transport = transportConnection.connectOrThrow( - /* caller */ "BMS.getOperationTypeFromTransport"); + /* caller */ "BMS.getBackupDestinationFromTransport"); if ((transport.getTransportFlags() & BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) { - return OperationType.MIGRATION; + return BackupDestination.DEVICE_TRANSFER; } else { - return OperationType.BACKUP; + return BackupDestination.CLOUD; } } finally { Binder.restoreCallingIdentity(oldCallingId); diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java index 379ae52018c4..65682f457957 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java +++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java @@ -315,7 +315,7 @@ public class FullBackupEngine { mAgent = backupManagerService.bindToAgentSynchronous( mPkg.applicationInfo, ApplicationThreadConstants.BACKUP_MODE_FULL, - mBackupEligibilityRules.getOperationType()); + mBackupEligibilityRules.getBackupDestination()); } return mAgent != null; } diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java index 95cc289d58b7..3ff6ba7e59c0 100644 --- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java +++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java @@ -20,7 +20,7 @@ import static com.android.server.backup.BackupManagerService.DEBUG; import static com.android.server.backup.BackupManagerService.MORE_DEBUG; import static com.android.server.backup.BackupManagerService.TAG; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.IBackupManagerMonitor; import android.app.backup.RestoreSet; import android.os.Handler; @@ -240,7 +240,7 @@ public class BackupHandler extends Handler { /* userInitiated */ false, /* nonIncremental */ false, backupManagerService.getEligibilityRulesForOperation( - OperationType.BACKUP)); + BackupDestination.CLOUD)); } catch (Exception e) { // unable to ask the transport its dir name -- transient failure, since // the above check succeeded. Try again next time. diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java index fd9c834540e7..ca92b6986731 100644 --- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java +++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java @@ -741,7 +741,7 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { agent = mBackupManagerService.bindToAgentSynchronous( packageInfo.applicationInfo, BACKUP_MODE_INCREMENTAL, - mBackupEligibilityRules.getOperationType()); + mBackupEligibilityRules.getBackupDestination()); if (agent == null) { mReporter.onAgentError(packageName); throw AgentException.transitory(); diff --git a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java index 8b1d5619a70d..d3e4f138f5da 100644 --- a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java +++ b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java @@ -16,8 +16,6 @@ package com.android.server.backup.restore; -import static android.app.backup.BackupManager.OperationType; - import static com.android.server.backup.BackupManagerService.DEBUG; import static com.android.server.backup.BackupManagerService.MORE_DEBUG; import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT; @@ -26,6 +24,7 @@ import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.IBackupManagerMonitor; import android.app.backup.IRestoreObserver; import android.app.backup.IRestoreSession; @@ -299,9 +298,9 @@ public class ActiveRestoreSession extends IRestoreSession.Stub { private BackupEligibilityRules getBackupEligibilityRules(RestoreSet restoreSet) { // TODO(b/182986784): Remove device name comparison once a designated field for operation // type is added to RestoreSet object. - int operationType = DEVICE_NAME_FOR_D2D_SET.equals(restoreSet.device) - ? OperationType.MIGRATION : OperationType.BACKUP; - return mBackupManagerService.getEligibilityRulesForOperation(operationType); + int backupDestination = DEVICE_NAME_FOR_D2D_SET.equals(restoreSet.device) + ? BackupDestination.DEVICE_TRANSFER : BackupDestination.CLOUD; + return mBackupManagerService.getEligibilityRulesForOperation(backupDestination); } public synchronized int restorePackage(String packageName, IRestoreObserver observer, diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java index e78c8d1ddcac..b042c3024034 100644 --- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java +++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java @@ -28,6 +28,7 @@ import android.annotation.NonNull; import android.app.ApplicationThreadConstants; import android.app.IBackupAgent; import android.app.backup.BackupAgent; +import android.app.backup.BackupAnnotations; import android.app.backup.BackupManager; import android.app.backup.FullBackup; import android.app.backup.IBackupManagerMonitor; @@ -398,7 +399,7 @@ public class FullRestoreEngine extends RestoreEngine { FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain) ? ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL : ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL, - mBackupEligibilityRules.getOperationType()); + mBackupEligibilityRules.getBackupDestination()); mAgentPackage = pkg; } catch (IOException | NameNotFoundException e) { // fall through to error handling @@ -707,7 +708,8 @@ public class FullRestoreEngine extends RestoreEngine { } private boolean isRestorableFile(FileMetadata info) { - if (mBackupEligibilityRules.getOperationType() == BackupManager.OperationType.MIGRATION) { + if (mBackupEligibilityRules.getBackupDestination() + == BackupAnnotations.BackupDestination.DEVICE_TRANSFER) { // Everything is eligible for device-to-device migration. return true; } diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java index 22af19e8d2cb..515a17272109 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java @@ -24,7 +24,7 @@ import static com.android.server.backup.BackupPasswordManager.PBKDF_FALLBACK; import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_HEADER_MAGIC; import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_VERSION; -import android.app.backup.BackupManager; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.IFullBackupRestoreObserver; import android.content.pm.PackageManagerInternal; import android.os.ParcelFileDescriptor; @@ -112,7 +112,7 @@ public class PerformAdbRestoreTask implements Runnable { BackupEligibilityRules eligibilityRules = new BackupEligibilityRules( mBackupManagerService.getPackageManager(), LocalServices.getService(PackageManagerInternal.class), - mBackupManagerService.getUserId(), BackupManager.OperationType.ADB_BACKUP); + mBackupManagerService.getUserId(), BackupDestination.ADB_BACKUP); FullRestoreEngine mEngine = new FullRestoreEngine(mBackupManagerService, mOperationStorage, null, mObserver, null, null, true, 0 /*unused*/, true, eligibilityRules); 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 9f89339a9149..18e28de75782 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -675,7 +675,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { mAgent = backupManagerService.bindToAgentSynchronous( mCurrentPackage.applicationInfo, ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL, - mBackupEligibilityRules.getOperationType()); + mBackupEligibilityRules.getBackupDestination()); if (mAgent == null) { Slog.w(TAG, "Can't find backup agent for " + packageName); mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor, @@ -1160,8 +1160,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { if (mIsSystemRestore && mPmAgent != null) { backupManagerService.setAncestralPackages(mPmAgent.getRestoredPackages()); backupManagerService.setAncestralToken(mToken); - backupManagerService.setAncestralOperationType( - mBackupEligibilityRules.getOperationType()); + backupManagerService.setAncestralBackupDestination( + mBackupEligibilityRules.getBackupDestination()); backupManagerService.writeRestoreTokens(); } diff --git a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java index d0300ff19178..7f0b56f82fac 100644 --- a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java +++ b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java @@ -23,7 +23,7 @@ import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_A import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import android.annotation.Nullable; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.BackupTransport; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; @@ -61,7 +61,7 @@ public class BackupEligibilityRules { private final PackageManager mPackageManager; private final PackageManagerInternal mPackageManagerInternal; private final int mUserId; - @OperationType private final int mOperationType; + @BackupDestination private final int mBackupDestination; /** * When this change is enabled, {@code adb backup} is automatically turned on for apps @@ -85,17 +85,17 @@ public class BackupEligibilityRules { PackageManagerInternal packageManagerInternal, int userId) { return new BackupEligibilityRules(packageManager, packageManagerInternal, userId, - OperationType.BACKUP); + BackupDestination.CLOUD); } public BackupEligibilityRules(PackageManager packageManager, PackageManagerInternal packageManagerInternal, int userId, - @OperationType int operationType) { + @BackupDestination int backupDestination) { mPackageManager = packageManager; mPackageManagerInternal = packageManagerInternal; mUserId = userId; - mOperationType = operationType; + mBackupDestination = backupDestination; } /** @@ -111,7 +111,7 @@ public class BackupEligibilityRules { * </ol> * * However, the above eligibility rules are ignored for non-system apps in in case of - * device-to-device migration, see {@link OperationType}. + * device-to-device migration, see {@link BackupDestination}. */ @VisibleForTesting public boolean appIsEligibleForBackup(ApplicationInfo app) { @@ -152,22 +152,22 @@ public class BackupEligibilityRules { /** * Check if this app allows backup. Apps can opt out of backup by stating * android:allowBackup="false" in their manifest. However, this flag is ignored for non-system - * apps during device-to-device migrations, see {@link OperationType}. + * apps during device-to-device migrations, see {@link BackupDestination}. * * @param app The app under check. * @return boolean indicating whether backup is allowed. */ public boolean isAppBackupAllowed(ApplicationInfo app) { boolean allowBackup = (app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0; - switch (mOperationType) { - case OperationType.MIGRATION: + switch (mBackupDestination) { + case BackupDestination.DEVICE_TRANSFER: // Backup / restore of all non-system apps is force allowed during // device-to-device migration. boolean isSystemApp = (app.flags & ApplicationInfo.FLAG_SYSTEM) != 0; boolean ignoreAllowBackup = !isSystemApp && CompatChanges.isChangeEnabled( IGNORE_ALLOW_BACKUP_IN_D2D, app.packageName, UserHandle.of(mUserId)); return ignoreAllowBackup || allowBackup; - case OperationType.ADB_BACKUP: + case BackupDestination.ADB_BACKUP: String packageName = app.packageName; if (packageName == null) { Slog.w(TAG, "Invalid ApplicationInfo object"); @@ -207,10 +207,10 @@ public class BackupEligibilityRules { // All other apps can use adb backup only when running in debuggable mode. return isDebuggable; } - case OperationType.BACKUP: + case BackupDestination.CLOUD: return allowBackup; default: - Slog.w(TAG, "Unknown operation type:" + mOperationType); + Slog.w(TAG, "Unknown operation type:" + mBackupDestination); return false; } } @@ -398,7 +398,7 @@ public class BackupEligibilityRules { } } - public int getOperationType() { - return mOperationType; + public int getBackupDestination() { + return mBackupDestination; } } diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java index ce7854d7368a..28141960f119 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -130,6 +130,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @Nullable private final @AssociationRequest.DeviceProfile String mDeviceProfile; @Nullable private final SecureWindowCallback mSecureWindowCallback; + @Nullable private final List<String> mDisplayCategories; /** * Creates a window policy controller that is generic to the different use cases of virtual @@ -168,7 +169,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @NonNull PipBlockedCallback pipBlockedCallback, @NonNull ActivityBlockedCallback activityBlockedCallback, @NonNull SecureWindowCallback secureWindowCallback, - @AssociationRequest.DeviceProfile String deviceProfile) { + @AssociationRequest.DeviceProfile String deviceProfile, + @NonNull List<String> displayCategories) { super(); mAllowedUsers = allowedUsers; mAllowedCrossTaskNavigations = new ArraySet<>(allowedCrossTaskNavigations); @@ -182,6 +184,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController mDeviceProfile = deviceProfile; mPipBlockedCallback = pipBlockedCallback; mSecureWindowCallback = secureWindowCallback; + mDisplayCategories = displayCategories; } /** @@ -319,7 +322,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController if (mDeviceProfile == null) { return true; } - // TODO(b/234075973) : Remove this once proper API is ready. + // TODO(b/234075973) : Remove this once proper API is ready. switch (mDeviceProfile) { case DEVICE_PROFILE_AUTOMOTIVE_PROJECTION: return false; @@ -350,6 +353,15 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } } + private boolean activityMatchesDisplayCategory(ActivityInfo activityInfo) { + if (mDisplayCategories.isEmpty()) { + return activityInfo.targetDisplayCategory == null; + } + return activityInfo.targetDisplayCategory != null + && mDisplayCategories.contains(activityInfo.targetDisplayCategory); + + } + private boolean canContainActivity(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { @@ -357,9 +369,17 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } ComponentName activityComponent = activityInfo.getComponentName(); if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) { - // The error dialog alerting users that streaming is blocked is always allowed. + // The error dialog alerting users that streaming is blocked is always allowed. Need to + // run before the clauses below to ensure error dialog always shows up. return true; } + if (!activityMatchesDisplayCategory(activityInfo)) { + Slog.d(TAG, String.format( + "The activity's target display category: %s is not found on virtual display" + + " with the following allowed display categories: %s", + activityInfo.targetDisplayCategory, mDisplayCategories.toString())); + return false; + } final UserHandle activityUser = UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid); if (!mAllowedUsers.contains(activityUser)) { diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index d83c80fcca6a..7e82918d621f 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -74,6 +74,7 @@ import com.android.server.companion.virtual.audio.VirtualAudioController; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; @@ -411,6 +412,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @Override // Binder call public void createVirtualKeyboard( int displayId, @@ -437,6 +439,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @Override // Binder call public void createVirtualMouse( int displayId, @@ -462,6 +465,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @Override // Binder call public void createVirtualTouchscreen( int displayId, @@ -625,7 +629,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mInputController.dump(fout); } - GenericWindowPolicyController createWindowPolicyController() { + GenericWindowPolicyController createWindowPolicyController( + @NonNull List<String> displayCategories) { synchronized (mVirtualDeviceLock) { final GenericWindowPolicyController gwpc = new GenericWindowPolicyController(FLAG_SECURE, @@ -640,7 +645,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub this::onEnteringPipBlocked, this::onActivityBlocked, this::onSecureWindowShown, - mAssociationInfo.getDeviceProfile()); + mAssociationInfo.getDeviceProfile(), + displayCategories); gwpc.registerRunningAppsChangedListener(/* listener= */ this); return gwpc; } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java index a8797a05ed24..fe26700f180b 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java @@ -332,7 +332,8 @@ public class VirtualDeviceManagerService extends SystemService { GenericWindowPolicyController gwpc; final long token = Binder.clearCallingIdentity(); try { - gwpc = virtualDeviceImpl.createWindowPolicyController(); + gwpc = virtualDeviceImpl.createWindowPolicyController( + virtualDisplayConfig.getDisplayCategories()); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/Android.bp b/services/core/Android.bp index 088eddbb00e3..a61a61b4f5c7 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -162,6 +162,7 @@ java_library_static { "android.hardware.biometrics.face-V1.0-java", "android.hardware.biometrics.fingerprint-V2.3-java", "android.hardware.oemlock-V1.0-java", + "android.hardware.oemlock-V1-java", "android.hardware.configstore-V1.1-java", "android.hardware.ir-V1-java", "android.hardware.rebootescrow-V1-java", diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index ca86021cd629..30d4b8b7bd4a 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -52,8 +52,8 @@ import android.telephony.Annotation; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; import android.telephony.BarringInfo; -import android.telephony.CallAttributes; import android.telephony.CallQuality; +import android.telephony.CallState; import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.CellSignalStrength; @@ -82,6 +82,7 @@ import android.telephony.TelephonyDisplayInfo; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsCallSession; import android.telephony.ims.ImsReasonInfo; import android.text.TextUtils; import android.util.ArrayMap; @@ -349,9 +350,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private CallQuality[] mCallQuality; - private CallAttributes[] mCallAttributes; + private ArrayList<List<CallState>> mCallStateLists; - // network type of the call associated with the mCallAttributes and mCallQuality + // network type of the call associated with the mCallStateLists and mCallQuality private int[] mCallNetworkType; private int[] mSrvccState; @@ -687,7 +688,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones); mCallQuality = copyOf(mCallQuality, mNumPhones); mCallNetworkType = copyOf(mCallNetworkType, mNumPhones); - mCallAttributes = copyOf(mCallAttributes, mNumPhones); mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones); mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones); mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones); @@ -707,6 +707,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { cutListToSize(mLinkCapacityEstimateLists, mNumPhones); cutListToSize(mCarrierPrivilegeStates, mNumPhones); cutListToSize(mCarrierServiceStates, mNumPhones); + cutListToSize(mCallStateLists, mNumPhones); return; } @@ -730,8 +731,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallDisconnectCause[i] = DisconnectCause.NOT_VALID; mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID; mCallQuality[i] = createCallQuality(); - mCallAttributes[i] = new CallAttributes(createPreciseCallState(), - TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality()); + mCallStateLists.add(i, new ArrayList<>()); mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN; mPreciseCallState[i] = createPreciseCallState(); mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; @@ -799,7 +799,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallPreciseDisconnectCause = new int[numPhones]; mCallQuality = new CallQuality[numPhones]; mCallNetworkType = new int[numPhones]; - mCallAttributes = new CallAttributes[numPhones]; + mCallStateLists = new ArrayList<>(); mPreciseDataConnectionStates = new ArrayList<>(); mCellInfo = new ArrayList<>(numPhones); mImsReasonInfo = new ArrayList<>(); @@ -837,8 +837,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallDisconnectCause[i] = DisconnectCause.NOT_VALID; mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID; mCallQuality[i] = createCallQuality(); - mCallAttributes[i] = new CallAttributes(createPreciseCallState(), - TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality()); + mCallStateLists.add(i, new ArrayList<>()); mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN; mPreciseCallState[i] = createPreciseCallState(); mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; @@ -1336,7 +1335,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) { try { - r.callback.onCallAttributesChanged(mCallAttributes[r.phoneId]); + r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId)); } catch (RemoteException ex) { remove(r.binder); } @@ -2171,11 +2170,30 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyPreciseCallState(int phoneId, int subId, int ringingCallState, - int foregroundCallState, int backgroundCallState) { + /** + * Send a notification to registrants that the precise call state has changed. + * + * @param phoneId the phoneId carrying the data connection + * @param subId the subscriptionId for the data connection + * @param callStates Array of PreciseCallState of foreground, background & ringing calls. + * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId()} for + * ringing, foreground & background calls. + * @param imsServiceTypes Array of IMS call service type for ringing, foreground & + * background calls. + * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls. + */ + public void notifyPreciseCallState(int phoneId, int subId, + @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds, + @Annotation.ImsCallServiceType int[] imsServiceTypes, + @Annotation.ImsCallType int[] imsCallTypes) { if (!checkNotifyPermission("notifyPreciseCallState()")) { return; } + + int ringingCallState = callStates[CallState.CALL_CLASSIFICATION_RINGING]; + int foregroundCallState = callStates[CallState.CALL_CLASSIFICATION_FOREGROUND]; + int backgroundCallState = callStates[CallState.CALL_CLASSIFICATION_BACKGROUND]; + synchronized (mRecords) { if (validatePhoneId(phoneId)) { mRingingCallState[phoneId] = ringingCallState; @@ -2186,11 +2204,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { backgroundCallState, DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID); - boolean notifyCallAttributes = true; + boolean notifyCallState = true; if (mCallQuality == null) { log("notifyPreciseCallState: mCallQuality is null, " + "skipping call attributes"); - notifyCallAttributes = false; + notifyCallState = false; } else { // If the precise call state is no longer active, reset the call network type // and call quality. @@ -2199,8 +2217,54 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallNetworkType[phoneId] = TelephonyManager.NETWORK_TYPE_UNKNOWN; mCallQuality[phoneId] = createCallQuality(); } - mCallAttributes[phoneId] = new CallAttributes(mPreciseCallState[phoneId], - mCallNetworkType[phoneId], mCallQuality[phoneId]); + mCallStateLists.get(phoneId).clear(); + if (foregroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) { + CallQuality callQuality = mCallQuality[phoneId]; + mCallStateLists.get(phoneId).add( + new CallState.Builder( + callStates[CallState.CALL_CLASSIFICATION_FOREGROUND]) + .setNetworkType(mCallNetworkType[phoneId]) + .setCallQuality(callQuality) + .setCallClassification( + CallState.CALL_CLASSIFICATION_FOREGROUND) + .setImsCallSessionId(imsCallIds[ + CallState.CALL_CLASSIFICATION_FOREGROUND]) + .setImsCallServiceType(imsServiceTypes[ + CallState.CALL_CLASSIFICATION_FOREGROUND]) + .setImsCallType(imsCallTypes[ + CallState.CALL_CLASSIFICATION_FOREGROUND]).build()); + + } + if (backgroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) { + mCallStateLists.get(phoneId).add( + new CallState.Builder( + callStates[CallState.CALL_CLASSIFICATION_BACKGROUND]) + .setNetworkType(mCallNetworkType[phoneId]) + .setCallQuality(createCallQuality()) + .setCallClassification( + CallState.CALL_CLASSIFICATION_BACKGROUND) + .setImsCallSessionId(imsCallIds[ + CallState.CALL_CLASSIFICATION_BACKGROUND]) + .setImsCallServiceType(imsServiceTypes[ + CallState.CALL_CLASSIFICATION_BACKGROUND]) + .setImsCallType(imsCallTypes[ + CallState.CALL_CLASSIFICATION_BACKGROUND]).build()); + } + if (ringingCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) { + mCallStateLists.get(phoneId).add( + new CallState.Builder( + callStates[CallState.CALL_CLASSIFICATION_RINGING]) + .setNetworkType(mCallNetworkType[phoneId]) + .setCallQuality(createCallQuality()) + .setCallClassification( + CallState.CALL_CLASSIFICATION_RINGING) + .setImsCallSessionId(imsCallIds[ + CallState.CALL_CLASSIFICATION_RINGING]) + .setImsCallServiceType(imsServiceTypes[ + CallState.CALL_CLASSIFICATION_RINGING]) + .setImsCallType(imsCallTypes[ + CallState.CALL_CLASSIFICATION_RINGING]).build()); + } } for (Record r : mRecords) { @@ -2213,11 +2277,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRemoveList.add(r.binder); } } - if (notifyCallAttributes && r.matchTelephonyCallbackEvent( + if (notifyCallState && r.matchTelephonyCallbackEvent( TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED) && idMatch(r, subId, phoneId)) { try { - r.callback.onCallAttributesChanged(mCallAttributes[phoneId]); + r.callback.onCallStatesChanged(mCallStateLists.get(phoneId)); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -2515,15 +2579,29 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // merge CallQuality with PreciseCallState and network type mCallQuality[phoneId] = callQuality; mCallNetworkType[phoneId] = callNetworkType; - mCallAttributes[phoneId] = new CallAttributes(mPreciseCallState[phoneId], - callNetworkType, callQuality); + if (mCallStateLists.get(phoneId).size() > 0 + && mCallStateLists.get(phoneId).get(0).getCallState() + == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) { + CallState prev = mCallStateLists.get(phoneId).remove(0); + mCallStateLists.get(phoneId).add( + 0, new CallState.Builder(prev.getCallState()) + .setNetworkType(callNetworkType) + .setCallQuality(callQuality) + .setCallClassification(prev.getCallClassification()) + .setImsCallSessionId(prev.getImsCallSessionId()) + .setImsCallServiceType(prev.getImsCallServiceType()) + .setImsCallType(prev.getImsCallType()).build()); + } else { + log("There is no active call to report CallQaulity"); + return; + } for (Record r : mRecords) { if (r.matchTelephonyCallbackEvent( TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED) && idMatch(r, subId, phoneId)) { try { - r.callback.onCallAttributesChanged(mCallAttributes[phoneId]); + r.callback.onCallStatesChanged(mCallStateLists.get(phoneId)); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -2991,7 +3069,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mSrvccState=" + mSrvccState[i]); pw.println("mCallPreciseDisconnectCause=" + mCallPreciseDisconnectCause[i]); pw.println("mCallQuality=" + mCallQuality[i]); - pw.println("mCallAttributes=" + mCallAttributes[i]); pw.println("mCallNetworkType=" + mCallNetworkType[i]); pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i)); pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]); diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 1534e635f1b2..4539e9eab424 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -32,6 +32,8 @@ import static android.app.ForegroundServiceTypePolicy.FGS_TYPE_POLICY_CHECK_UNKN import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; +import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE; +import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; import static android.os.PowerExemptionManager.REASON_ACTIVE_DEVICE_ADMIN; import static android.os.PowerExemptionManager.REASON_ACTIVITY_STARTER; import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD; @@ -110,7 +112,6 @@ import android.app.ActivityThread; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.ForegroundServiceStartNotAllowedException; -import android.app.ForegroundServiceTypeNotAllowedException; import android.app.ForegroundServiceTypePolicy; import android.app.ForegroundServiceTypePolicy.ForegroundServicePolicyCheckCode; import android.app.ForegroundServiceTypePolicy.ForegroundServiceTypePermission; @@ -118,6 +119,8 @@ import android.app.ForegroundServiceTypePolicy.ForegroundServiceTypePolicyInfo; import android.app.IApplicationThread; import android.app.IForegroundServiceObserver; import android.app.IServiceConnection; +import android.app.InvalidForegroundServiceTypeException; +import android.app.MissingForegroundServiceTypeException; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -225,7 +228,8 @@ public final class ActiveServices { private static final boolean DEBUG_DELAYED_SERVICE = DEBUG_SERVICE; private static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE; - private static final boolean DEBUG_SHORT_SERVICE = DEBUG_SERVICE; + // STOPSHIP(b/260012573) turn it off. + private static final boolean DEBUG_SHORT_SERVICE = true; // DEBUG_SERVICE; private static final boolean LOG_SERVICE_START_STOP = DEBUG_SERVICE; @@ -1284,6 +1288,8 @@ public final class ActiveServices { return; } + maybeStopShortFgsTimeoutLocked(service); + final int uid = service.appInfo.uid; final String packageName = service.name.getPackageName(); final String serviceName = service.name.getClassName(); @@ -1467,6 +1473,8 @@ public final class ActiveServices { } } + maybeStopShortFgsTimeoutLocked(r); + final int uid = r.appInfo.uid; final String packageName = r.name.getPackageName(); final String serviceName = r.name.getClassName(); @@ -1781,6 +1789,7 @@ public final class ActiveServices { if (notification == null) { throw new IllegalArgumentException("null notification"); } + final int foregroundServiceStartType = foregroundServiceType; // Instant apps need permission to create foreground services. if (r.appInfo.isInstantApp()) { final int mode = mAm.getAppOpsManager().checkOpNoThrow( @@ -1833,6 +1842,14 @@ public final class ActiveServices { + String.format("0x%08X", manifestType) + " in service element of manifest file"); } + if ((foregroundServiceType & FOREGROUND_SERVICE_TYPE_SHORT_SERVICE) != 0 + && foregroundServiceType != FOREGROUND_SERVICE_TYPE_SHORT_SERVICE) { + Slog.w(TAG_SERVICE, "startForeground(): FOREGROUND_SERVICE_TYPE_SHORT_SERVICE" + + " is combined with other types. SHORT_SERVICE will be ignored."); + // In this case, the service will be handled as a non-short, regular FGS + // anyway, so we just remove the SHORT_SERVICE type. + foregroundServiceType &= ~FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; + } } boolean alreadyStartedOp = false; @@ -1883,14 +1900,51 @@ public final class ActiveServices { int fgsTypeCheckCode = FGS_TYPE_POLICY_CHECK_UNKNOWN; if (!ignoreForeground) { - // TODO(short-service): There's a known long-standing bug that allows - // a abound service to become "foreground" if setForeground() is called - // (without actually "starting" it). - // Unfortunately we can't just "fix" it because some apps are relying on it, - // but this will cause a problem to short-fgs, so we should disallow it if - // this happens and the type is SHORT_SERVICE. - // - // OTOH, if a valid short-service (which has to be "started"), happens to + if (foregroundServiceType == FOREGROUND_SERVICE_TYPE_SHORT_SERVICE + && !r.startRequested) { + // There's a long standing bug that allows a bound service to become + // a foreground service *even when it's not started*. + // Unfortunately, there are apps relying on this behavior, so we can't just + // suddenly disallow it. + // However, this would be very problematic if used with a short-FGS, so we + // explicitly disallow this combination. + // TODO(short-service): Change to another exception type? + throw new IllegalStateException( + "startForeground(SHORT_SERVICE) called on a service that's not" + + " started."); + } + // If the service is already an FGS, and the type is changing, then we + // may need to do some extra work here. + if (r.isForeground && (r.foregroundServiceType != foregroundServiceType)) { + // TODO(short-service): Consider transitions: + // A. Short -> other types: + // Apply the BG restriction again. Don't just allow it. + // i.e. unless the app is in a situation where it's allowed to start + // a FGS, this transition shouldn't be allowed. + // ... But think about it more, there may be a case this should be + // allowed. + // + // If the transition is allowed, stop the timeout. + // If the transition is _not_ allowed... keep the timeout? + // + // B. Short -> Short: + // Allowed, but the timeout won't reset. The original timeout is used. + // C. Other -> short: + // This should always be allowed. + // A timeout should start. + + // For now, let's just disallow transition from / to SHORT_SERVICE. + final boolean isNewTypeShortFgs = + foregroundServiceType == FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; + if (r.isShortFgs() != isNewTypeShortFgs) { + // TODO(short-service): We should (probably) allow it. + throw new IllegalArgumentException( + "setForeground(): Changing foreground service type from / to " + + " SHORT_SERVICE is now allowed"); + } + } + + // If a valid short-service (which has to be "started"), happens to // also be bound, then we still _will_ apply a timeout, because it still has // to be stopped. if (r.mStartForegroundCount == 0) { @@ -1929,24 +1983,6 @@ public final class ActiveServices { // on the same sarvice after it's created, regardless of whether // stopForeground() has been called or not. - // TODO(short-service): Consider transitions: - // A. Short -> other types: - // Apply the BG restriction again. Don't just allow it. - // i.e. unless the app is in a situation where it's allowed to start - // a FGS, this transition shouldn't be allowed. - // ... But think about it more, there may be a case this should be - // allowed. - // - // If the transition is allowed, stop the timeout. - // If the transition is _not_ allowed... keep the timeout? - // - // B. Short -> Short: - // This should be the same as case A - // If this is allowed, the new timeout should start. - // C. Other -> short: - // This should always be allowed. - // A timeout should start. - // The second or later time startForeground() is called after service is // started. Check for app state again. setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(), @@ -1985,7 +2021,8 @@ public final class ActiveServices { if (foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) { fgsTypeResult = validateForegroundServiceType(r, foregroundServiceType, - ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE); + ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE, + foregroundServiceStartType); } else { int fgsTypes = foregroundServiceType; // If the service has declared some unknown types which might be coming @@ -2000,7 +2037,7 @@ public final class ActiveServices { serviceType != 0; serviceType = Integer.highestOneBit(fgsTypes)) { fgsTypeResult = validateForegroundServiceType(r, - serviceType, defaultFgsTypes); + serviceType, defaultFgsTypes, foregroundServiceStartType); fgsTypes &= ~serviceType; if (fgsTypeResult.first != FGS_TYPE_POLICY_CHECK_OK) { break; @@ -2102,8 +2139,11 @@ public final class ActiveServices { mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE); - // TODO(short-service): Start counting a timeout. - + // Note, we'll get here if setForeground(SHORT_SERVICE) is called on a + // already short-fgs. + // In that case, because ShortFgsInfo is already set, this method + // will be noop. + maybeStartShortFgsTimeoutAndUpdateShortFgsInfoLocked(r); } else { if (DEBUG_FOREGROUND_SERVICE) { Slog.d(TAG, "Suppressing startForeground() for FAS " + r); @@ -2137,7 +2177,7 @@ public final class ActiveServices { decActiveForegroundAppLocked(smap, r); } - // TODO(short-service): Stop the timeout. (any better place to do it?) + maybeStopShortFgsTimeoutLocked(r); // Adjust notification handling before setting isForeground to false, because // that state is relevant to the notification policy side. @@ -2227,7 +2267,8 @@ public final class ActiveServices { @NonNull private Pair<Integer, RuntimeException> validateForegroundServiceType(ServiceRecord r, @ForegroundServiceType int type, - @ForegroundServiceType int defaultToType) { + @ForegroundServiceType int defaultToType, + @ForegroundServiceType int startType) { final ForegroundServiceTypePolicy policy = ForegroundServiceTypePolicy.getDefaultPolicy(); final ForegroundServiceTypePolicyInfo policyInfo = policy.getForegroundServiceTypePolicyInfo(type, defaultToType); @@ -2246,12 +2287,20 @@ public final class ActiveServices { Slog.w(TAG, msg); } break; case FGS_TYPE_POLICY_CHECK_DISABLED: { - exception = new ForegroundServiceTypeNotAllowedException( - "Starting FGS with type " - + ServiceInfo.foregroundServiceTypeToLabel(type) - + " callerApp=" + r.app - + " targetSDK=" + r.app.info.targetSdkVersion - + " has been prohibited"); + if (startType == FOREGROUND_SERVICE_TYPE_MANIFEST + && type == FOREGROUND_SERVICE_TYPE_NONE) { + exception = new MissingForegroundServiceTypeException( + "Starting FGS without a type " + + " callerApp=" + r.app + + " targetSDK=" + r.app.info.targetSdkVersion); + } else { + exception = new InvalidForegroundServiceTypeException( + "Starting FGS with type " + + ServiceInfo.foregroundServiceTypeToLabel(type) + + " callerApp=" + r.app + + " targetSDK=" + r.app.info.targetSdkVersion + + " has been prohibited"); + } } break; case FGS_TYPE_POLICY_CHECK_PERMISSION_DENIED_PERMISSIVE: { final String msg = "Starting FGS with type " @@ -2873,6 +2922,90 @@ public final class ActiveServices { psr.setHasReportedForegroundServices(anyForeground); } + void unscheduleShortFgsTimeoutLocked(ServiceRecord sr) { + mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG, sr); + mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_SHORT_FGS_TIMEOUT_MSG, sr); + } + + /** + * If {@code sr} is of a short-fgs, start a short-FGS timeout. + */ + private void maybeStartShortFgsTimeoutAndUpdateShortFgsInfoLocked(ServiceRecord sr) { + if (!sr.isShortFgs()) { + return; + } + if (DEBUG_SHORT_SERVICE) { + Slog.i(TAG_SERVICE, "Short FGS started: " + sr); + } + if (sr.hasShortFgsInfo()) { + sr.getShortFgsInfo().update(); + } else { + sr.setShortFgsInfo(SystemClock.uptimeMillis()); + } + unscheduleShortFgsTimeoutLocked(sr); // Do it just in case + + final Message msg = mAm.mHandler.obtainMessage( + ActivityManagerService.SERVICE_SHORT_FGS_TIMEOUT_MSG, sr); + mAm.mHandler.sendMessageAtTime(msg, sr.getShortFgsInfo().getTimeoutTime()); + } + + /** + * Stop the timeout for a ServiceRecord, if it's of a short-FGS. + */ + private void maybeStopShortFgsTimeoutLocked(ServiceRecord sr) { + if (!sr.isShortFgs()) { + return; + } + if (DEBUG_SHORT_SERVICE) { + Slog.i(TAG_SERVICE, "Stop short FGS timeout: " + sr); + } + sr.clearShortFgsInfo(); + unscheduleShortFgsTimeoutLocked(sr); + } + + void onShortFgsTimeout(ServiceRecord sr) { + synchronized (mAm) { + if (!sr.shouldTriggerShortFgsTimeout()) { + return; + } + Slog.e(TAG_SERVICE, "Short FGS timed out: " + sr); + try { + sr.app.getThread().scheduleTimeoutService(sr, sr.getShortFgsInfo().getStartId()); + } catch (RemoteException e) { + // TODO(short-service): Anything to do here? + } + // Schedule the ANR timeout. + final Message msg = mAm.mHandler.obtainMessage( + ActivityManagerService.SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG, sr); + mAm.mHandler.sendMessageAtTime(msg, sr.getShortFgsInfo().getAnrTime()); + } + } + + void onShortFgsAnrTimeout(ServiceRecord sr) { + final String reason = "A foreground service of FOREGROUND_SERVICE_TYPE_SHORT_SERVICE" + + " did not stop within a timeout: " + sr.getComponentName(); + + final TimeoutRecord tr = TimeoutRecord.forShortFgsTimeout(reason); + + // TODO(short-service): TODO Add SHORT_FGS_TIMEOUT to AnrLatencyTracker + tr.mLatencyTracker.waitingOnAMSLockStarted(); + synchronized (mAm) { + tr.mLatencyTracker.waitingOnAMSLockEnded(); + + if (!sr.shouldTriggerShortFgsAnr()) { + return; + } + + final String message = "Short FGS ANR'ed: " + sr; + if (DEBUG_SHORT_SERVICE) { + Slog.wtf(TAG_SERVICE, message); + } else { + Slog.e(TAG_SERVICE, message); + } + mAm.appNotResponding(sr.app, tr); + } + } + private void updateAllowlistManagerLocked(ProcessServiceRecord psr) { psr.mAllowlistManager = false; for (int i = psr.numberOfRunningServices() - 1; i >= 0; i--) { @@ -2884,6 +3017,7 @@ public final class ActiveServices { } } + // TODO(short-service): Hmm what is it? Should we stop the timeout here? private void stopServiceAndUpdateAllowlistManagerLocked(ServiceRecord service) { final ProcessServiceRecord psr = service.app.mServices; psr.stopService(service); @@ -4165,7 +4299,7 @@ public final class ActiveServices { /** * Reschedule service restarts based on if the extra delays are enabled or not. * - * @param prevEnable The previous state of whether or not it's enabled. + * @param prevEnabled The previous state of whether or not it's enabled. * @param curEnabled The current state of whether or not it's enabled. * @param now The uptimeMillis */ @@ -4850,13 +4984,6 @@ public final class ActiveServices { Slog.i(TAG, "Bring down service for " + debugReason + " :" + r.toString()); } - // TODO(short-service): Hmm, when the app stops a short-fgs, we should stop the timeout - // here. - // However we have a couple if's here and if these conditions are met, we stop here - // without bringing down the service. - // We need to make sure this can't be used (somehow) to keep having a short-FGS running - // while having the timeout stopped. - if (isServiceNeededLocked(r, knowConn, hasConn)) { return; } @@ -4873,6 +5000,13 @@ public final class ActiveServices { //Slog.i(TAG, "Bring down service:"); //r.dump(" "); + if (r.isShortFgs()) { + // FGS can be stopped without the app calling stopService() or stopSelf(), + // due to force-app-standby, or from Task Manager. + Slog.w(TAG_SERVICE, "Short FGS brought down without stopping: " + r); + maybeStopShortFgsTimeoutLocked(r); + } + // Report to all of the connections that the service is no longer // available. ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index 046403d409af..2d69667da575 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -954,7 +954,7 @@ final class ActivityManagerConstants extends ContentObserver { static final long DEFAULT_SHORT_FGS_TIMEOUT_DURATION = 60_000; /** @see #KEY_SHORT_FGS_TIMEOUT_DURATION */ - public static volatile long mShortFgsTimeoutDuration = DEFAULT_SHORT_FGS_TIMEOUT_DURATION; + public volatile long mShortFgsTimeoutDuration = DEFAULT_SHORT_FGS_TIMEOUT_DURATION; /** * If a "short service" doesn't finish within this after the timeout ( @@ -967,7 +967,7 @@ final class ActivityManagerConstants extends ContentObserver { static final long DEFAULT_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION = 5_000; /** @see #KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION */ - public static volatile long mShortFgsProcStateExtraWaitDuration = + public volatile long mShortFgsProcStateExtraWaitDuration = DEFAULT_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION; /** @@ -983,7 +983,7 @@ final class ActivityManagerConstants extends ContentObserver { static final long DEFAULT_SHORT_FGS_ANR_EXTRA_WAIT_DURATION = 10_000; /** @see #KEY_SHORT_FGS_ANR_EXTRA_WAIT_DURATION */ - public static volatile long mShortFgsAnrExtraWaitDuration = + public volatile long mShortFgsAnrExtraWaitDuration = DEFAULT_SHORT_FGS_ANR_EXTRA_WAIT_DURATION; private final OnPropertiesChangedListener mOnDeviceConfigChangedListener = diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c779ea9b4916..35b46c1104f7 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -206,7 +206,7 @@ import android.app.ProfilerInfo; import android.app.SyncNotedAppOp; import android.app.WaitResult; import android.app.assist.ActivityId; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.IBackupManager; import android.app.compat.CompatChanges; import android.app.job.JobParameters; @@ -1563,6 +1563,8 @@ public class ActivityManagerService extends IActivityManager.Stub static final int WAIT_FOR_CONTENT_PROVIDER_TIMEOUT_MSG = 73; static final int DISPATCH_SENDING_BROADCAST_EVENT = 74; static final int DISPATCH_BINDING_SERVICE_EVENT = 75; + static final int SERVICE_SHORT_FGS_TIMEOUT_MSG = 76; + static final int SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG = 77; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1897,6 +1899,12 @@ public class ActivityManagerService extends IActivityManager.Stub mBindServiceEventListeners.forEach(l -> l.onBindingService((String) msg.obj, msg.arg1)); } break; + case SERVICE_SHORT_FGS_TIMEOUT_MSG: { + mServices.onShortFgsTimeout((ServiceRecord) msg.obj); + } break; + case SERVICE_SHORT_FGS_ANR_TIMEOUT_MSG: { + mServices.onShortFgsAnrTimeout((ServiceRecord) msg.obj); + } break; } } } @@ -5179,7 +5187,8 @@ public class ActivityManagerService extends IActivityManager.Stub PackageManager.NOTIFY_PACKAGE_USE_BACKUP); try { thread.scheduleCreateBackupAgent(backupTarget.appInfo, - backupTarget.backupMode, backupTarget.userId, backupTarget.operationType); + backupTarget.backupMode, backupTarget.userId, + backupTarget.backupDestination); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); badApp = true; @@ -6141,6 +6150,7 @@ public class ActivityManagerService extends IActivityManager.Stub /** * This can be called with or without the global lock held. */ + @PermissionMethod(anyOf = true) private void enforceCallingHasAtLeastOnePermission(String func, String... permissions) { for (String permission : permissions) { if (checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { @@ -13129,7 +13139,7 @@ public class ActivityManagerService extends IActivityManager.Stub // instantiated. The backup agent will invoke backupAgentCreated() on the // activity manager to announce its creation. public boolean bindBackupAgent(String packageName, int backupMode, int targetUserId, - @OperationType int operationType) { + @BackupDestination int backupDestination) { if (DEBUG_BACKUP) { Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode + " targetUserId=" + targetUserId + " callingUid = " + Binder.getCallingUid() @@ -13196,7 +13206,7 @@ public class ActivityManagerService extends IActivityManager.Stub + app.packageName + ": " + e); } - BackupRecord r = new BackupRecord(app, backupMode, targetUserId, operationType); + BackupRecord r = new BackupRecord(app, backupMode, targetUserId, backupDestination); ComponentName hostingName = (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL) ? new ComponentName(app.packageName, app.backupAgentName) @@ -13238,7 +13248,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc); try { thread.scheduleCreateBackupAgent(app, backupMode, targetUserId, - operationType); + backupDestination); } catch (RemoteException e) { // Will time out on the backup manager side } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 10f5a369824f..7946cb74f117 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -257,6 +257,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return runForceStop(pw); case "stop-app": return runStopApp(pw); + case "clear-recent-apps": + return runClearRecentApps(pw); case "fgs-notification-rate-limit": return runFgsNotificationRateLimit(pw); case "crash": @@ -1239,6 +1241,11 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } + int runClearRecentApps(PrintWriter pw) throws RemoteException { + mTaskInterface.removeAllVisibleRecentTasks(); + return 0; + } + int runFgsNotificationRateLimit(PrintWriter pw) throws RemoteException { final String toggleValue = getNextArgRequired(); final boolean enable; diff --git a/services/core/java/com/android/server/am/BackupRecord.java b/services/core/java/com/android/server/am/BackupRecord.java index d4198562c1dd..0b056d7883bf 100644 --- a/services/core/java/com/android/server/am/BackupRecord.java +++ b/services/core/java/com/android/server/am/BackupRecord.java @@ -16,8 +16,7 @@ package com.android.server.am; -import android.app.backup.BackupManager; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; import android.content.pm.ApplicationInfo; /** @hide */ @@ -32,16 +31,16 @@ final class BackupRecord { final ApplicationInfo appInfo; // information about BackupAgent's app final int userId; // user for which backup is performed final int backupMode; // full backup / incremental / restore - @OperationType final int operationType; // see BackupManager#OperationType + @BackupDestination final int backupDestination; // see BackupAnnotations#BackupDestination ProcessRecord app; // where this agent is running or null // ----- Implementation ----- - BackupRecord(ApplicationInfo _appInfo, int _backupMode, int _userId, int _operationType) { + BackupRecord(ApplicationInfo _appInfo, int _backupMode, int _userId, int _backupDestination) { appInfo = _appInfo; backupMode = _backupMode; userId = _userId; - operationType = _operationType; + backupDestination = _backupDestination; } public String toString() { diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 8082e45b3238..66a8babe224e 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1818,21 +1818,31 @@ public class OomAdjuster { newAdj = PERCEPTIBLE_APP_ADJ; newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; - } else if (psr.hasForegroundServices() && !psr.hasNonShortForegroundServices()) { - // For short FGS. - adjType = "fg-service-short"; - // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ (which uses MEDIUM_APP_ADJ + 1) - // from short-FGS. - // (We use +1 and +2, not +0 and +1, to be consistent with the following - // RECENT_FOREGROUND_APP_ADJ tweak) - newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1; - - // Short-FGS gets a below-BFGS procstate, so it can't start another FGS from it. - newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; - - // Same as EJ, we explicitly grant network access to short FGS, - // even when battery saver or data saver is enabled. - capabilityFromFGS |= PROCESS_CAPABILITY_NETWORK; + } else if (psr.hasForegroundServices()) { + // If we get here, hasNonShortForegroundServices() must be false. + + // TODO(short-service): Proactively run OomAjudster when the grace period finish. + if (psr.areAllShortForegroundServicesProcstateTimedOut(now)) { + // All the short-FGSes within this process are timed out. Don't promote to FGS. + // TODO(short-service): Should we set some unique oom-adj to make it detectable, + // in a long trace? + } else { + // For short FGS. + adjType = "fg-service-short"; + // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ + // (which uses MEDIUM_APP_ADJ + 1) + // from short-FGS. + // (We use +1 and +2, not +0 and +1, to be consistent with the following + // RECENT_FOREGROUND_APP_ADJ tweak) + newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1; + + // Short-FGS gets a below-BFGS procstate, so it can't start another FGS from it. + newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; + + // Same as EJ, we explicitly grant network access to short FGS, + // even when battery saver or data saver is enabled. + capabilityFromFGS |= PROCESS_CAPABILITY_NETWORK; + } } if (adjType != null) { diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java index 13264db01680..df442e83dc9e 100644 --- a/services/core/java/com/android/server/am/ProcessServiceRecord.java +++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java @@ -175,6 +175,9 @@ final class ProcessServiceRecord { } } + /** + * @return true if this process has any foreground services (even timed-out short-FGS) + */ boolean hasForegroundServices() { return mHasForegroundServices; } @@ -224,6 +227,33 @@ final class ProcessServiceRecord { return mFgServiceTypes != ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; } + /** + * @return if this process: + * - has at least one short-FGS + * - has no other types of FGS + * - and all the short-FGSes are procstate-timed out. + */ + boolean areAllShortForegroundServicesProcstateTimedOut(long nowUptime) { + if (!mHasForegroundServices) { // Process has no FGS? + return false; + } + if (hasNonShortForegroundServices()) { // Any non-short FGS running? + return false; + } + // Now we need to look at all short-FGS within the process and see if all of them are + // procstate-timed-out or not. + for (int i = mServices.size() - 1; i >= 0; i--) { + final ServiceRecord sr = mServices.valueAt(i); + if (!sr.isShortFgs() || !sr.hasShortFgsInfo()) { + continue; + } + if (sr.getShortFgsInfo().getProcStateDemoteTime() >= nowUptime) { + return false; + } + } + return true; + } + int getReportedForegroundServiceTypes() { return mRepFgServiceTypes; } diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 0468152acdd8..547c20b55a3c 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -315,6 +315,87 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final ArrayList<StartItem> pendingStarts = new ArrayList<StartItem>(); // start() arguments that haven't yet been delivered. + /** + * Information specific to "SHORT_SERVICE" FGS. + */ + class ShortFgsInfo { + /** Time FGS started */ + private final long mStartTime; + + /** + * Copied from {@link #mStartForegroundCount}. If this is different from the parent's, + * that means this instance is stale. + */ + private int mStartForegroundCount; + + /** Service's "start ID" when this short-service started. */ + private int mStartId; + + ShortFgsInfo(long startTime) { + mStartTime = startTime; + update(); + } + + /** + * Update {@link #mStartForegroundCount} and {@link #mStartId}. + * (but not {@link #mStartTime}) + */ + public void update() { + this.mStartForegroundCount = ServiceRecord.this.mStartForegroundCount; + this.mStartId = getLastStartId(); + } + + long getStartTime() { + return mStartTime; + } + + int getStartForegroundCount() { + return mStartForegroundCount; + } + + int getStartId() { + return mStartId; + } + + /** + * @return whether this {@link ShortFgsInfo} is still "current" or not -- i.e. + * it's "start foreground count" is the same as that of the ServiceRecord's. + * + * Note, we do _not_ check the "start id" here, because the start id increments if the + * app calls startService() or startForegroundService() on the same service, + * but that will _not_ update the ShortFgsInfo, and will not extend the timeout. + * + * TODO(short-service): Make sure, calling startService will not extend or remove the + * timeout, in CTS. + */ + boolean isCurrent() { + return this.mStartForegroundCount == ServiceRecord.this.mStartForegroundCount; + } + + /** Time when Service.onTimeout() should be called */ + long getTimeoutTime() { + return mStartTime + ams.mConstants.mShortFgsTimeoutDuration; + } + + /** Time when the procstate should be lowered. */ + long getProcStateDemoteTime() { + return mStartTime + ams.mConstants.mShortFgsTimeoutDuration + + ams.mConstants.mShortFgsProcStateExtraWaitDuration; + } + + /** Time when the app should be declared ANR. */ + long getAnrTime() { + return mStartTime + ams.mConstants.mShortFgsTimeoutDuration + + ams.mConstants.mShortFgsAnrExtraWaitDuration; + } + } + + /** + * Keep track of short-fgs specific information. This field gets cleared when the timeout + * stops. + */ + private ShortFgsInfo mShortFgsInfo; + void dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now) { final int N = list.size(); for (int i=0; i<N; i++) { @@ -456,6 +537,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } } proto.end(token); + + // TODO(short-service) Add FGS info } void dump(PrintWriter pw, String prefix) { @@ -508,8 +591,25 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } if (isForeground || foregroundId != 0) { pw.print(prefix); pw.print("isForeground="); pw.print(isForeground); - pw.print(" foregroundId="); pw.print(foregroundId); - pw.print(" foregroundNoti="); pw.println(foregroundNoti); + pw.print(" foregroundId="); pw.print(foregroundId); + pw.printf(" types=%08X", foregroundServiceType); + pw.print(" foregroundNoti="); pw.println(foregroundNoti); + + if (isShortFgs() && mShortFgsInfo != null) { + pw.print(prefix); pw.print("isShortFgs=true"); + pw.print(" startId="); pw.print(mShortFgsInfo.getStartId()); + pw.print(" startForegroundCount="); + pw.print(mShortFgsInfo.getStartForegroundCount()); + pw.print(" startTime="); + TimeUtils.formatDuration(mShortFgsInfo.getStartTime(), now, pw); + pw.print(" timeout="); + TimeUtils.formatDuration(mShortFgsInfo.getTimeoutTime(), now, pw); + pw.print(" demoteTime="); + TimeUtils.formatDuration(mShortFgsInfo.getProcStateDemoteTime(), now, pw); + pw.print(" anrTime="); + TimeUtils.formatDuration(mShortFgsInfo.getAnrTime(), now, pw); + pw.println(); + } } if (mIsFgsDelegate) { pw.print(prefix); pw.print("isFgsDelegate="); pw.println(mIsFgsDelegate); @@ -590,6 +690,32 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } } + /** Used only for tests */ + private ServiceRecord(ActivityManagerService ams) { + this.ams = ams; + name = null; + instanceName = null; + shortInstanceName = null; + definingPackageName = null; + definingUid = 0; + intent = null; + serviceInfo = null; + userId = 0; + packageName = null; + processName = null; + permission = null; + exported = false; + restarter = null; + createRealTime = 0; + isSdkSandbox = false; + sdkSandboxClientAppUid = 0; + sdkSandboxClientAppPackage = null; + } + + public static ServiceRecord newEmptyInstanceForTest(ActivityManagerService ams) { + return new ServiceRecord(ams); + } + ServiceRecord(ActivityManagerService ams, ComponentName name, ComponentName instanceName, String definingPackageName, int definingUid, Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, @@ -1238,4 +1364,66 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN return isForeground && (foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE); } + + public ShortFgsInfo getShortFgsInfo() { + return isShortFgs() ? mShortFgsInfo : null; + } + + /** + * Call it when a short FGS starts. + */ + public void setShortFgsInfo(long uptimeNow) { + this.mShortFgsInfo = new ShortFgsInfo(uptimeNow); + } + + /** @return whether {@link #mShortFgsInfo} is set or not. */ + public boolean hasShortFgsInfo() { + return mShortFgsInfo != null; + } + + /** + * Call it when a short FGS stops. + */ + public void clearShortFgsInfo() { + this.mShortFgsInfo = null; + } + + /** + * @return true if it's a short FGS that's still up and running, and should be timed out. + */ + public boolean shouldTriggerShortFgsTimeout() { + if (!isAppAlive()) { + return false; + } + if (!this.startRequested || !isShortFgs() || mShortFgsInfo == null + || !mShortFgsInfo.isCurrent()) { + return false; + } + return mShortFgsInfo.getTimeoutTime() < SystemClock.uptimeMillis(); + } + + /** + * @return true if it's a short FGS that's still up and running, and should be declared + * an ANR. + */ + public boolean shouldTriggerShortFgsAnr() { + if (!isAppAlive()) { + return false; + } + if (!this.startRequested || !isShortFgs() || mShortFgsInfo == null + || !mShortFgsInfo.isCurrent()) { + return false; + } + return mShortFgsInfo.getAnrTime() < SystemClock.uptimeMillis(); + } + + private boolean isAppAlive() { + if (app == null) { + return false; + } + if (app.getThread() == null || app.isKilled() || app.isKilledByAm()) { + return false; + } + return true; + } } diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index f16347f33f71..f22624c32676 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -104,6 +104,7 @@ public class SettingsToPropertiesMapper { DeviceConfig.NAMESPACE_VIRTUALIZATION_FRAMEWORK_NATIVE, DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT, DeviceConfig.NAMESPACE_MEMORY_SAFETY_NATIVE, + DeviceConfig.NAMESPACE_HDMI_CONTROL }; private final String[] mGlobalSettings; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 3cf53ef73d0f..ae929c4dc5a1 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3622,6 +3622,18 @@ public class AudioService extends IAudioService.Stub } } + // TODO enforce MODIFY_AUDIO_SYSTEM_SETTINGS when defined + private void enforceModifyAudioRoutingOrSystemSettingsPermission() { + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + != PackageManager.PERMISSION_GRANTED + /*&& mContext.checkCallingOrSelfPermission( + android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS) + != PackageManager.PERMISSION_DENIED*/) { + throw new SecurityException( + "Missing MODIFY_AUDIO_ROUTING or MODIFY_AUDIO_SYSTEM_SETTINGS permission"); + } + } + private void enforceAccessUltrasoundPermission() { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_ULTRASOUND) != PackageManager.PERMISSION_GRANTED) { @@ -3734,20 +3746,35 @@ public class AudioService extends IAudioService.Stub } /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes) - * Part of service interface, check permissions and parameters here */ + * Part of service interface, check permissions and parameters here + * Note calling package is for logging purposes only, not to be trusted + */ public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, - @NonNull String callingPackage, @Nullable String attributionTag) { - enforceModifyAudioRoutingPermission(); + @NonNull String callingPackage) { + enforceModifyAudioRoutingOrSystemSettingsPermission(); Objects.requireNonNull(vi); Objects.requireNonNull(ada); Objects.requireNonNull(callingPackage); + if (!vi.hasStreamType()) { Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); return; } int index = vi.getVolumeIndex(); - if (index == VolumeInfo.INDEX_NOT_SET) { - throw new IllegalArgumentException("changing device volume requires a volume index"); + if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { + throw new IllegalArgumentException( + "changing device volume requires a volume index or mute command"); + } + + // TODO handle unmuting if current audio device + // if a stream is not muted but the VolumeInfo is for muting, set the volume index + // for the device to min volume + if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) { + setStreamVolumeWithAttributionInt(vi.getStreamType(), + mStreamStates[vi.getStreamType()].getMinIndex(), + /*flags*/ 0, + ada, callingPackage, null); + return; } AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage @@ -3772,7 +3799,7 @@ public class AudioService extends IAudioService.Stub } } setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0, - ada, callingPackage, attributionTag); + ada, callingPackage, null); } /** Retain API for unsupported app usage */ @@ -4682,6 +4709,36 @@ public class AudioService extends IAudioService.Stub } } + /** + * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes) + */ + public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi, + @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) { + enforceModifyAudioRoutingOrSystemSettingsPermission(); + Objects.requireNonNull(vi); + Objects.requireNonNull(ada); + Objects.requireNonNull(callingPackage); + if (!vi.hasStreamType()) { + Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); + return getDefaultVolumeInfo(); + } + + int streamType = vi.getStreamType(); + final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi); + vib.setMinVolumeIndex(mStreamStates[streamType].mIndexMin); + vib.setMaxVolumeIndex(mStreamStates[streamType].mIndexMax); + synchronized (VolumeStreamState.class) { + final int index; + if (isFixedVolumeDevice(ada.getInternalType())) { + index = (mStreamStates[streamType].mIndexMax + 5) / 10; + } else { + index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10; + } + vib.setVolumeIndex(index); + return vib.setMuted(mStreamStates[streamType].mIsMuted).build(); + } + } + /** @see AudioManager#getStreamMaxVolume(int) */ public int getStreamMaxVolume(int streamType) { ensureValidStreamType(streamType); @@ -4722,7 +4779,6 @@ public class AudioService extends IAudioService.Stub sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC) .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC)) .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC)) - .setMuted(false) .build(); } return sDefaultVolumeInfo; @@ -7124,6 +7180,24 @@ public class AudioService extends IAudioService.Stub state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") .record(); mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller); + // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System + // Client. For example, the device can start with the Audio System Client unavailable. + // When the feature is activated the client becomes available, therefore Audio Service + // requests a new HDMI Audio System Client instance when the ARC status is changed. + if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) { + updateHdmiAudioSystemClient(); + } + } + + /** + * Replace the current HDMI Audio System Client. + * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}. + */ + private void updateHdmiAudioSystemClient() { + Slog.d(TAG, "Hdmi Audio System Client is updated"); + synchronized (mHdmiClientLock) { + mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); + } } /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */ @@ -7965,6 +8039,23 @@ public class AudioService extends IAudioService.Stub } } + public @NonNull VolumeInfo getVolumeInfo(int device) { + synchronized (VolumeStreamState.class) { + int index = mIndexMap.get(device, -1); + if (index == -1) { + // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT + index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); + } + final VolumeInfo vi = new VolumeInfo.Builder(mStreamType) + .setMinVolumeIndex(mIndexMin) + .setMaxVolumeIndex(mIndexMax) + .setVolumeIndex(index) + .setMuted(isFullyMuted()) + .build(); + return vi; + } + } + public boolean hasIndexForDevice(int device) { synchronized (VolumeStreamState.class) { return (mIndexMap.get(device, -1) != -1); diff --git a/services/core/java/com/android/server/backup/SystemBackupAgent.java b/services/core/java/com/android/server/backup/SystemBackupAgent.java index d39d2d1eefb7..1b20e43c966c 100644 --- a/services/core/java/com/android/server/backup/SystemBackupAgent.java +++ b/services/core/java/com/android/server/backup/SystemBackupAgent.java @@ -18,9 +18,9 @@ package com.android.server.backup; import android.app.IWallpaperManager; import android.app.backup.BackupAgentHelper; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.BackupDataInput; import android.app.backup.BackupHelper; -import android.app.backup.BackupManager; import android.app.backup.FullBackup; import android.app.backup.FullBackupDataOutput; import android.app.backup.WallpaperBackupHelper; @@ -89,8 +89,8 @@ public class SystemBackupAgent extends BackupAgentHelper { private int mUserId = UserHandle.USER_SYSTEM; @Override - public void onCreate(UserHandle user, @BackupManager.OperationType int operationType) { - super.onCreate(user, operationType); + public void onCreate(UserHandle user, @BackupDestination int backupDestination) { + super.onCreate(user, backupDestination); mUserId = user.getIdentifier(); diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 9ded42aa6539..1f58a1c40fd8 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -299,7 +299,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private boolean mAppliedAutoBrightness; private boolean mAppliedDimming; private boolean mAppliedLowPower; - private boolean mAppliedTemporaryBrightness; private boolean mAppliedTemporaryAutoBrightnessAdjustment; private boolean mAppliedBrightnessBoost; private boolean mAppliedThrottling; @@ -395,11 +394,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // behalf of the user. private float mCurrentScreenBrightnessSetting; - // The temporary screen brightness. Typically set when a user is interacting with the - // brightness slider but hasn't settled on a choice yet. Set to - // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set. - private float mTemporaryScreenBrightness; - // The current screen brightness while in VR mode. private float mScreenBrightnessForVr; @@ -566,7 +560,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mCurrentScreenBrightnessSetting = getScreenBrightnessSetting(); mScreenBrightnessForVr = getScreenBrightnessForVrSetting(); mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); - mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; @@ -1218,16 +1211,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); - // Use the temporary screen brightness if there isn't an override, either from - // WindowManager or based on the display state. - if (isValidBrightnessValue(mTemporaryScreenBrightness)) { - brightnessState = mTemporaryScreenBrightness; - mAppliedTemporaryBrightness = true; - mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY); - } else { - mAppliedTemporaryBrightness = false; - } - final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment(); // Use the autobrightness adjustment override if set. @@ -1414,7 +1397,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // Skip the animation when the screen is off or suspended or transition to/from VR. boolean brightnessAdjusted = false; final boolean brightnessIsTemporary = - mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment; + (mBrightnessReason.getReason() == BrightnessReason.REASON_TEMPORARY) + || mAppliedTemporaryAutoBrightnessAdjustment; if (!mPendingScreenOff) { if (mSkipScreenOnBrightnessRamp) { if (state == Display.STATE_ON) { @@ -2202,13 +2186,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) { mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; - mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mDisplayBrightnessController + .setTemporaryBrightness(PowerManager.BRIGHTNESS_INVALID_FLOAT); return false; } setCurrentScreenBrightness(mPendingScreenBrightnessSetting); mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting; mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; - mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + mDisplayBrightnessController + .setTemporaryBrightness(PowerManager.BRIGHTNESS_INVALID_FLOAT); return true; } @@ -2291,7 +2277,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness); pw.println(" mPendingScreenBrightnessSetting=" + mPendingScreenBrightnessSetting); - pw.println(" mTemporaryScreenBrightness=" + mTemporaryScreenBrightness); pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); pw.println(" mBrightnessReason=" + mBrightnessReason); pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment); @@ -2301,7 +2286,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal pw.println(" mAppliedDimming=" + mAppliedDimming); pw.println(" mAppliedLowPower=" + mAppliedLowPower); pw.println(" mAppliedThrottling=" + mAppliedThrottling); - pw.println(" mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness); pw.println(" mAppliedTemporaryAutoBrightnessAdjustment=" + mAppliedTemporaryAutoBrightnessAdjustment); pw.println(" mAppliedBrightnessBoost=" + mAppliedBrightnessBoost); @@ -2541,7 +2525,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal case MSG_SET_TEMPORARY_BRIGHTNESS: // TODO: Should we have a a timeout for the temporary brightness? - mTemporaryScreenBrightness = Float.intBitsToFloat(msg.arg1); + mDisplayBrightnessController + .setTemporaryBrightness(Float.intBitsToFloat(msg.arg1)); updatePowerState(); break; diff --git a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java index d62b1ee96798..fd4e296ae002 100644 --- a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java +++ b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java @@ -28,7 +28,7 @@ public final class BrightnessUtils { * Checks whether the brightness is within the valid brightness range, not including off. */ public static boolean isValidBrightnessValue(float brightness) { - return brightness >= PowerManager.BRIGHTNESS_MIN + return !Float.isNaN(brightness) && brightness >= PowerManager.BRIGHTNESS_MIN && brightness <= PowerManager.BRIGHTNESS_MAX; } diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java index 80b5e65909c8..bdc8d9dbb043 100644 --- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java +++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java @@ -68,6 +68,21 @@ public final class DisplayBrightnessController { } /** + * Sets the temporary brightness + */ + public void setTemporaryBrightness(Float temporaryBrightness) { + mDisplayBrightnessStrategySelector.getTemporaryDisplayBrightnessStrategy() + .setTemporaryScreenBrightness(temporaryBrightness); + } + + /** + * Returns the current selected DisplayBrightnessStrategy + */ + public DisplayBrightnessStrategy getCurrentDisplayBrightnessStrategy() { + return mDisplayBrightnessStrategy; + } + + /** * Returns a boolean flag indicating if the light sensor is to be used to decide the screen * brightness when dozing */ diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java index b83b13b7da4c..4759b7df69ab 100644 --- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java +++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java @@ -19,6 +19,7 @@ package com.android.server.display.brightness; import android.annotation.NonNull; import android.content.Context; import android.hardware.display.DisplayManagerInternal; +import android.util.IndentingPrintWriter; import android.util.Slog; import android.view.Display; @@ -29,6 +30,7 @@ import com.android.server.display.brightness.strategy.DozeBrightnessStrategy; import com.android.server.display.brightness.strategy.InvalidBrightnessStrategy; import com.android.server.display.brightness.strategy.OverrideBrightnessStrategy; import com.android.server.display.brightness.strategy.ScreenOffBrightnessStrategy; +import com.android.server.display.brightness.strategy.TemporaryBrightnessStrategy; import java.io.PrintWriter; @@ -48,7 +50,9 @@ public class DisplayBrightnessStrategySelector { // The brightness strategy used to manage the brightness state when the request state is // invalid. private final OverrideBrightnessStrategy mOverrideBrightnessStrategy; - // The brightness strategy used to manage the brightness state request is invalid. + // The brightness strategy used to manage the brightness state in temporary state + private final TemporaryBrightnessStrategy mTemporaryBrightnessStrategy; + // The brightness strategy used to manage the brightness state when the request is invalid. private final InvalidBrightnessStrategy mInvalidBrightnessStrategy; // We take note of the old brightness strategy so that we can know when the strategy changes. @@ -67,6 +71,7 @@ public class DisplayBrightnessStrategySelector { mDozeBrightnessStrategy = injector.getDozeBrightnessStrategy(); mScreenOffBrightnessStrategy = injector.getScreenOffBrightnessStrategy(); mOverrideBrightnessStrategy = injector.getOverrideBrightnessStrategy(); + mTemporaryBrightnessStrategy = injector.getTemporaryBrightnessStrategy(); mInvalidBrightnessStrategy = injector.getInvalidBrightnessStrategy(); mAllowAutoBrightnessWhileDozingConfig = context.getResources().getBoolean( R.bool.config_allowAutoBrightnessWhileDozing); @@ -89,6 +94,9 @@ public class DisplayBrightnessStrategySelector { } else if (BrightnessUtils .isValidBrightnessValue(displayPowerRequest.screenBrightnessOverride)) { displayBrightnessStrategy = mOverrideBrightnessStrategy; + } else if (BrightnessUtils.isValidBrightnessValue( + mTemporaryBrightnessStrategy.getTemporaryScreenBrightness())) { + displayBrightnessStrategy = mTemporaryBrightnessStrategy; } if (!mOldBrightnessStrategyName.equals(displayBrightnessStrategy.getName())) { @@ -101,6 +109,10 @@ public class DisplayBrightnessStrategySelector { return displayBrightnessStrategy; } + public TemporaryBrightnessStrategy getTemporaryDisplayBrightnessStrategy() { + return mTemporaryBrightnessStrategy; + } + /** * Returns a boolean flag indicating if the light sensor is to be used to decide the screen * brightness when dozing @@ -120,6 +132,8 @@ public class DisplayBrightnessStrategySelector { writer.println( " mAllowAutoBrightnessWhileDozingConfig= " + mAllowAutoBrightnessWhileDozingConfig); + IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " "); + mTemporaryBrightnessStrategy.dump(ipw); } /** @@ -152,6 +166,10 @@ public class DisplayBrightnessStrategySelector { return new OverrideBrightnessStrategy(); } + TemporaryBrightnessStrategy getTemporaryBrightnessStrategy() { + return new TemporaryBrightnessStrategy(); + } + InvalidBrightnessStrategy getInvalidBrightnessStrategy() { return new InvalidBrightnessStrategy(); } diff --git a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java new file mode 100644 index 000000000000..f8063f3f3c30 --- /dev/null +++ b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display.brightness.strategy; + +import android.hardware.display.DisplayManagerInternal; +import android.os.PowerManager; + +import com.android.server.display.DisplayBrightnessState; +import com.android.server.display.brightness.BrightnessReason; +import com.android.server.display.brightness.BrightnessUtils; + +import java.io.PrintWriter; + +/** + * Manages the brightness of the display when the system brightness is temporary + */ +public class TemporaryBrightnessStrategy implements DisplayBrightnessStrategy { + // The temporary screen brightness. Typically set when a user is interacting with the + // brightness slider but hasn't settled on a choice yet. Set to + // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set. + private float mTemporaryScreenBrightness; + + public TemporaryBrightnessStrategy() { + mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; + } + + // Use the temporary screen brightness if there isn't an override, either from + // WindowManager or based on the display state. + @Override + public DisplayBrightnessState updateBrightness( + DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) { + // Todo(brup): Introduce a validator class and add validations before setting the brightness + DisplayBrightnessState displayBrightnessState = + BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_TEMPORARY, + mTemporaryScreenBrightness, + mTemporaryScreenBrightness); + mTemporaryScreenBrightness = Float.NaN; + return displayBrightnessState; + } + + @Override + public String getName() { + return "TemporaryBrightnessStrategy"; + } + + public float getTemporaryScreenBrightness() { + return mTemporaryScreenBrightness; + } + + public void setTemporaryScreenBrightness(float temporaryScreenBrightness) { + mTemporaryScreenBrightness = temporaryScreenBrightness; + } + + /** + * Dumps the state of this class. + */ + public void dump(PrintWriter writer) { + writer.println("TemporaryBrightnessStrategy:"); + writer.println(" mTemporaryScreenBrightness:" + mTemporaryScreenBrightness); + } +} diff --git a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java index 049a339957cb..4855be68e676 100644 --- a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java +++ b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java @@ -27,7 +27,7 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction { private static final int STATE_ARC_TERMINATED = 2; // the required maximum response time specified in CEC 9.2 - private static final int TIMEOUT_MS = 1000; + public static final int TIMEOUT_MS = 1000; ArcTerminationActionFromAvr(HdmiCecLocalDevice source) { super(source); @@ -85,6 +85,8 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction { } private void handleTerminateArcTimeout() { + // Disable ARC if TV didn't respond with <Report ARC Terminated> in time. + audioSystem().setArcStatus(false); HdmiLogger.debug("handleTerminateArcTimeout"); finish(); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java index 79820a222dc0..6925507adaa4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java @@ -16,7 +16,7 @@ package com.android.server.hdmi; -import static android.hardware.hdmi.HdmiControlManager.CecSettingName; +import static android.hardware.hdmi.HdmiControlManager.SettingName; import android.annotation.IntDef; import android.annotation.NonNull; @@ -45,7 +45,10 @@ import java.util.concurrent.Executor; /** * The {@link HdmiCecConfig} class is used for getting information about - * available HDMI CEC settings. + * available HDMI control settings, including CEC settings and eARC settings. + * + * TODO(b/240379115): rename this class and related methods in this package to represent that the + * settings storage mechanism applies to all HDMI control settings and not just CEC settings. */ public class HdmiCecConfig { private static final String TAG = "HdmiCecConfig"; @@ -105,7 +108,7 @@ public class HdmiCecConfig { * * @param setting name of a CEC setting that changed */ - void onChange(@NonNull @CecSettingName String setting); + void onChange(@NonNull @SettingName String setting); } /** @@ -204,21 +207,21 @@ public class HdmiCecConfig { protected class Setting { @NonNull private final Context mContext; - @NonNull private final @CecSettingName String mName; + @NonNull private final @SettingName String mName; private final boolean mUserConfigurable; private Value mDefaultValue = null; private List<Value> mAllowedValues = new ArrayList<>(); Setting(@NonNull Context context, - @NonNull @CecSettingName String name, + @NonNull @SettingName String name, int userConfResId) { mContext = context; mName = name; mUserConfigurable = mContext.getResources().getBoolean(userConfResId); } - public @CecSettingName String getName() { + public @SettingName String getName() { return mName; } @@ -315,6 +318,16 @@ public class HdmiCecConfig { R.bool.config_cecRoutingControlDisabled_allowed, R.bool.config_cecRoutingControlDisabled_default); + Setting soundbarMode = registerSetting( + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, + R.bool.config_cecSoundbarMode_userConfigurable); + soundbarMode.registerValue(HdmiControlManager.SOUNDBAR_MODE_ENABLED, + R.bool.config_cecSoundbarModeEnabled_allowed, + R.bool.config_cecSoundbarModeEnabled_default); + soundbarMode.registerValue(HdmiControlManager.SOUNDBAR_MODE_DISABLED, + R.bool.config_cecSoundbarModeDisabled_allowed, + R.bool.config_cecSoundbarModeDisabled_default); + Setting powerControlMode = registerSetting( HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, R.bool.config_cecPowerControlMode_userConfigurable); @@ -663,6 +676,16 @@ public class HdmiCecConfig { R.bool.config_cecQuerySadMaxDisabled_allowed, R.bool.config_cecQuerySadMaxDisabled_default); + Setting earcEnabled = registerSetting( + HdmiControlManager.SETTING_NAME_EARC_ENABLED, + R.bool.config_earcEnabled_userConfigurable); + earcEnabled.registerValue(HdmiControlManager.EARC_FEATURE_ENABLED, + R.bool.config_earcFeatureEnabled_allowed, + R.bool.config_earcFeatureEnabled_default); + earcEnabled.registerValue(HdmiControlManager.EARC_FEATURE_DISABLED, + R.bool.config_earcFeatureDisabled_allowed, + R.bool.config_earcFeatureDisabled_default); + verifySettings(); } @@ -670,7 +693,7 @@ public class HdmiCecConfig { this(context, new StorageAdapter(context)); } - private Setting registerSetting(@NonNull @CecSettingName String name, + private Setting registerSetting(@NonNull @SettingName String name, int userConfResId) { Setting setting = new Setting(mContext, name, userConfResId); mSettings.put(name, setting); @@ -701,6 +724,8 @@ public class HdmiCecConfig { return STORAGE_SHARED_PREFS; case HdmiControlManager.CEC_SETTING_NAME_ROUTING_CONTROL: return STORAGE_SHARED_PREFS; + case HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE: + return STORAGE_SHARED_PREFS; case HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE: return STORAGE_SHARED_PREFS; case HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE: @@ -760,6 +785,8 @@ public class HdmiCecConfig { return STORAGE_SHARED_PREFS; case HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX: return STORAGE_SHARED_PREFS; + case HdmiControlManager.SETTING_NAME_EARC_ENABLED: + return STORAGE_SHARED_PREFS; default: throw new VerificationException("Invalid CEC setting '" + setting.getName() + "' storage."); @@ -774,6 +801,8 @@ public class HdmiCecConfig { return setting.getName(); case HdmiControlManager.CEC_SETTING_NAME_ROUTING_CONTROL: return setting.getName(); + case HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE: + return setting.getName(); case HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE: return setting.getName(); case HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE: @@ -833,6 +862,8 @@ public class HdmiCecConfig { return setting.getName(); case HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX: return setting.getName(); + case HdmiControlManager.SETTING_NAME_EARC_ENABLED: + return setting.getName(); default: throw new VerificationException("Invalid CEC setting '" + setting.getName() + "' storage key."); @@ -871,14 +902,6 @@ public class HdmiCecConfig { } } - private void notifySettingChanged(@NonNull @CecSettingName String name) { - Setting setting = getSetting(name); - if (setting == null) { - throw new IllegalArgumentException("Setting '" + name + "' does not exist."); - } - notifySettingChanged(setting); - } - protected void notifySettingChanged(@NonNull Setting setting) { synchronized (mLock) { ArrayMap<SettingChangeListener, Executor> listeners = @@ -902,7 +925,7 @@ public class HdmiCecConfig { /** * Register change listener for a given setting name using DirectExecutor. */ - public void registerChangeListener(@NonNull @CecSettingName String name, + public void registerChangeListener(@NonNull @SettingName String name, SettingChangeListener listener) { registerChangeListener(name, listener, ConcurrentUtils.DIRECT_EXECUTOR); } @@ -910,7 +933,7 @@ public class HdmiCecConfig { /** * Register change listener for a given setting name and executor. */ - public void registerChangeListener(@NonNull @CecSettingName String name, + public void registerChangeListener(@NonNull @SettingName String name, SettingChangeListener listener, Executor executor) { Setting setting = getSetting(name); @@ -933,7 +956,7 @@ public class HdmiCecConfig { /** * Remove change listener for a given setting name. */ - public void removeChangeListener(@NonNull @CecSettingName String name, + public void removeChangeListener(@NonNull @SettingName String name, SettingChangeListener listener) { Setting setting = getSetting(name); if (setting == null) { @@ -954,14 +977,14 @@ public class HdmiCecConfig { /** * Returns a list of all settings based on the XML metadata. */ - public @CecSettingName List<String> getAllSettings() { + public @SettingName List<String> getAllSettings() { return new ArrayList<>(mSettings.keySet()); } /** * Returns a list of user-modifiable settings based on the XML metadata. */ - public @CecSettingName List<String> getUserSettings() { + public @SettingName List<String> getUserSettings() { List<String> settings = new ArrayList<>(); for (Setting setting: mSettings.values()) { if (setting.getUserConfigurable()) { @@ -975,7 +998,7 @@ public class HdmiCecConfig { * For a given setting name returns true if and only if the value type of that * setting is a string. */ - public boolean isStringValueType(@NonNull @CecSettingName String name) { + public boolean isStringValueType(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -987,7 +1010,7 @@ public class HdmiCecConfig { * For a given setting name returns true if and only if the value type of that * setting is an int. */ - public boolean isIntValueType(@NonNull @CecSettingName String name) { + public boolean isIntValueType(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -998,7 +1021,7 @@ public class HdmiCecConfig { /** * For a given setting name returns values that are allowed for that setting (string). */ - public List<String> getAllowedStringValues(@NonNull @CecSettingName String name) { + public List<String> getAllowedStringValues(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -1017,7 +1040,7 @@ public class HdmiCecConfig { /** * For a given setting name returns values that are allowed for that setting (string). */ - public List<Integer> getAllowedIntValues(@NonNull @CecSettingName String name) { + public List<Integer> getAllowedIntValues(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -1036,7 +1059,7 @@ public class HdmiCecConfig { /** * For a given setting name returns the default value for that setting (string). */ - public String getDefaultStringValue(@NonNull @CecSettingName String name) { + public String getDefaultStringValue(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -1051,7 +1074,7 @@ public class HdmiCecConfig { /** * For a given setting name returns the default value for that setting (int). */ - public int getDefaultIntValue(@NonNull @CecSettingName String name) { + public int getDefaultIntValue(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -1066,7 +1089,7 @@ public class HdmiCecConfig { /** * For a given setting name returns the current value of that setting (string). */ - public String getStringValue(@NonNull @CecSettingName String name) { + public String getStringValue(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -1082,7 +1105,7 @@ public class HdmiCecConfig { /** * For a given setting name returns the current value of that setting (int). */ - public int getIntValue(@NonNull @CecSettingName String name) { + public int getIntValue(@NonNull @SettingName String name) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -1100,7 +1123,7 @@ public class HdmiCecConfig { /** * For a given setting name and value sets the current value of that setting (string). */ - public void setStringValue(@NonNull @CecSettingName String name, @NonNull String value) { + public void setStringValue(@NonNull @SettingName String name, @NonNull String value) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); @@ -1123,7 +1146,7 @@ public class HdmiCecConfig { /** * For a given setting name and value sets the current value of that setting (int). */ - public void setIntValue(@NonNull @CecSettingName String name, int value) { + public void setIntValue(@NonNull @SettingName String name, int value) { Setting setting = getSetting(name); if (setting == null) { throw new IllegalArgumentException("Setting '" + name + "' does not exist."); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index 5c1b33cb3120..50edd0e8e008 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -636,7 +636,7 @@ final class HdmiCecController { void onReceiveCommand(HdmiCecMessage message) { assertRunOnServiceThread(); if (((ACTION_ON_RECEIVE_MSG & CEC_DISABLED_IGNORE) == 0) - && !mService.isControlEnabled() + && !mService.isCecControlEnabled() && !HdmiCecMessage.isCecTransportMessage(message.getOpcode())) { if ((ACTION_ON_RECEIVE_MSG & CEC_DISABLED_LOG_WARNING) != 0) { HdmiLogger.warning("Message " + message + " received when cec disabled"); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index 2622cef32241..b4d7fb9d9153 100755 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -698,7 +698,7 @@ abstract class HdmiCecLocalDevice { protected void reportFeatures() { List<Integer> localDeviceTypes = new ArrayList<>(); - for (HdmiCecLocalDevice localDevice : mService.getAllLocalDevices()) { + for (HdmiCecLocalDevice localDevice : mService.getAllCecLocalDevices()) { localDeviceTypes.add(localDevice.mDeviceType); } @@ -728,7 +728,7 @@ abstract class HdmiCecLocalDevice { protected int handleStandby(HdmiCecMessage message) { assertRunOnServiceThread(); // Seq #12 - if (mService.isControlEnabled() + if (mService.isCecControlEnabled() && !mService.isProhibitMode() && mService.isPowerOnOrTransient()) { mService.standby(); @@ -1359,7 +1359,8 @@ abstract class HdmiCecLocalDevice { List<SendKeyAction> action = getActions(SendKeyAction.class); int logicalAddress = findAudioReceiverAddress(); if (logicalAddress == Constants.ADDR_INVALID - || logicalAddress == mDeviceInfo.getLogicalAddress()) { + || mService.getAllCecLocalDevices().stream().anyMatch( + device -> device.getDeviceInfo().getLogicalAddress() == logicalAddress)) { // Don't send key event to invalid device or itself. Slog.w( TAG, diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index 32ff5e220825..ccaa9255dbd4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -226,6 +226,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @Override @ServiceThreadOnly protected void disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback) { + terminateAudioReturnChannel(); + super.disableDevice(initiatedByCec, callback); assertRunOnServiceThread(); mService.unregisterTvInputCallback(mTvInputCallback); @@ -884,7 +886,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { private void notifyArcStatusToAudioService(boolean enabled) { // Note that we don't set any name to ARC. mService.getAudioManager() - .setWiredDeviceConnectionState(AudioSystem.DEVICE_IN_HDMI, enabled ? 1 : 0, "", ""); + .setWiredDeviceConnectionState(AudioSystem.DEVICE_IN_HDMI_ARC, enabled ? 1 : 0, "", ""); } void reportAudioStatus(int source) { @@ -1042,7 +1044,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); return; } - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { setRoutingPort(portId); setLocalActivePort(portId); invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE); @@ -1088,6 +1090,16 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } } + private void terminateAudioReturnChannel() { + // remove pending initiation actions + removeAction(ArcInitiationActionFromAvr.class); + if (!isArcEnabled() + || !mService.readBooleanSystemProperty(Constants.PROPERTY_ARC_SUPPORT, true)) { + return; + } + addAndStartAction(new ArcTerminationActionFromAvr(this)); + } + /** Reports if System Audio Mode is supported by the connected TV */ interface TvSystemAudioModeSupportedCallback { @@ -1312,6 +1324,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @ServiceThreadOnly private void launchDeviceDiscovery() { assertRunOnServiceThread(); + if (mService.isDeviceDiscoveryHandledByPlayback()) { + return; + } if (hasAction(DeviceDiscoveryAction.class)) { Slog.i(TAG, "Device Discovery Action is in progress. Restarting."); removeAction(DeviceDiscoveryAction.class); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index e6c2e7cae23e..3ec3f9446954 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -137,7 +137,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { // Since we removed all devices when it starts and device discovery action // does not poll local devices, we should put device info of local device // manually here. - for (HdmiCecLocalDevice device : mService.getAllLocalDevices()) { + for (HdmiCecLocalDevice device : mService.getAllCecLocalDevices()) { mService.getHdmiCecNetwork().addCecDevice(device.getDeviceInfo()); } @@ -190,7 +190,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { if (isAlreadyActiveSource(targetDevice, targetAddress, callback)) { return; } - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { setActiveSource(targetDevice, "HdmiCecLocalDevicePlayback#deviceSelect()"); invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE); return; @@ -239,7 +239,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { @ServiceThreadOnly protected void onStandby(boolean initiatedByCec, int standbyAction) { assertRunOnServiceThread(); - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { return; } boolean wasActiveSource = isActiveSource(); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 8a22ab968165..96e7b03ec5a0 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -259,7 +259,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); return; } - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { setActiveSource(targetDevice, "HdmiCecLocalDeviceTv#deviceSelect()"); invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE); return; @@ -272,7 +272,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { private void handleSelectInternalSource() { assertRunOnServiceThread(); // Seq #18 - if (mService.isControlEnabled() + if (mService.isCecControlEnabled() && getActiveSource().logicalAddress != getDeviceInfo().getLogicalAddress()) { updateActiveSource( getDeviceInfo().getLogicalAddress(), @@ -371,7 +371,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { return; } getActiveSource().invalidate(); - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { setActivePortId(portId); invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE); return; @@ -694,7 +694,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { // Since we removed all devices when it starts and // device discovery action does not poll local devices, // we should put device info of local device manually here - for (HdmiCecLocalDevice device : mService.getAllLocalDevices()) { + for (HdmiCecLocalDevice device : mService.getAllCecLocalDevices()) { mService.getHdmiCecNetwork().addCecDevice(device.getDeviceInfo()); } @@ -742,7 +742,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { // Seq #32 void changeSystemAudioMode(boolean enabled, IHdmiControlCallback callback) { assertRunOnServiceThread(); - if (!mService.isControlEnabled() || hasAction(DeviceDiscoveryAction.class)) { + if (!mService.isCecControlEnabled() || hasAction(DeviceDiscoveryAction.class)) { setSystemAudioMode(false); invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE); return; @@ -1181,7 +1181,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } private boolean isMessageForSystemAudio(HdmiCecMessage message) { - return mService.isControlEnabled() + return mService.isCecControlEnabled() && message.getSource() == Constants.ADDR_AUDIO_SYSTEM && (message.getDestination() == Constants.ADDR_TV || message.getDestination() == Constants.ADDR_BROADCAST) @@ -1330,7 +1330,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { removeAction(SystemAudioAutoInitiationAction.class); removeAction(VolumeControlAction.class); - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { setSystemAudioMode(false); } } @@ -1376,7 +1376,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { protected void onStandby(boolean initiatedByCec, int standbyAction) { assertRunOnServiceThread(); // Seq #11 - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { return; } boolean sendStandbyOnSleep = @@ -1415,7 +1415,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { @Constants.HandleMessageResult int startOneTouchRecord(int recorderAddress, byte[] recordSource) { assertRunOnServiceThread(); - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { Slog.w(TAG, "Can not start one touch record. CEC control is disabled."); announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED); return Constants.ABORT_NOT_IN_CORRECT_MODE; @@ -1444,7 +1444,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { @ServiceThreadOnly void stopOneTouchRecord(int recorderAddress) { assertRunOnServiceThread(); - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { Slog.w(TAG, "Can not stop one touch record. CEC control is disabled."); announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED); return; @@ -1478,7 +1478,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { @ServiceThreadOnly void startTimerRecording(int recorderAddress, int sourceType, byte[] recordSource) { assertRunOnServiceThread(); - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { Slog.w(TAG, "Can not start one touch record. CEC control is disabled."); announceTimerRecordingResult(recorderAddress, TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED); @@ -1514,7 +1514,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { @ServiceThreadOnly void clearTimerRecording(int recorderAddress, int sourceType, byte[] recordSource) { assertRunOnServiceThread(); - if (!mService.isControlEnabled()) { + if (!mService.isCecControlEnabled()) { Slog.w(TAG, "Can not start one touch record. CEC control is disabled."); announceClearTimerRecordingResult(recorderAddress, CLEAR_TIMER_STATUS_CEC_DISABLE); return; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecPowerStatusController.java b/services/core/java/com/android/server/hdmi/HdmiCecPowerStatusController.java index 552ff376a2d6..f819f00b51e2 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecPowerStatusController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecPowerStatusController.java @@ -75,7 +75,7 @@ class HdmiCecPowerStatusController { } private void sendReportPowerStatus(int powerStatus) { - for (HdmiCecLocalDevice localDevice : mHdmiControlService.getAllLocalDevices()) { + for (HdmiCecLocalDevice localDevice : mHdmiControlService.getAllCecLocalDevices()) { mHdmiControlService.sendCecCommand( HdmiCecMessageBuilder.buildReportPowerStatus( localDevice.getDeviceInfo().getLogicalAddress(), diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 1ae1b5b5185d..43cd71ae519c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -19,6 +19,8 @@ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE; import static android.hardware.hdmi.HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; +import static android.hardware.hdmi.HdmiControlManager.SOUNDBAR_MODE_DISABLED; +import static android.hardware.hdmi.HdmiControlManager.SOUNDBAR_MODE_ENABLED; import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED; import static com.android.server.hdmi.Constants.DISABLED; @@ -188,6 +190,7 @@ public class HdmiControlService extends SystemService { static final int INITIATED_BY_SCREEN_ON = 2; static final int INITIATED_BY_WAKE_UP_MESSAGE = 3; static final int INITIATED_BY_HOTPLUG = 4; + static final int INITIATED_BY_SOUNDBAR_MODE = 5; // The reason code representing the intent action that drives the standby // procedure. The procedure starts either by Intent.ACTION_SCREEN_OFF or @@ -336,8 +339,8 @@ public class HdmiControlService extends SystemService { // Used to synchronize the access to the service. private final Object mLock = new Object(); - // Type of logical devices hosted in the system. Stored in the unmodifiable list. - private final List<Integer> mLocalDevices; + // Type of CEC logical devices hosted in the system. Stored in the unmodifiable list. + private final List<Integer> mCecLocalDevices; // List of records for HDMI control status change listener for death monitoring. @GuardedBy("mLock") @@ -496,7 +499,7 @@ public class HdmiControlService extends SystemService { @VisibleForTesting HdmiControlService(Context context, List<Integer> deviceTypes, AudioDeviceVolumeManagerWrapperInterface audioDeviceVolumeManager) { super(context); - mLocalDevices = deviceTypes; + mCecLocalDevices = deviceTypes; mSettingsObserver = new SettingsObserver(mHandler); mHdmiCecConfig = new HdmiCecConfig(context); mAudioDeviceVolumeManager = audioDeviceVolumeManager; @@ -504,7 +507,7 @@ public class HdmiControlService extends SystemService { public HdmiControlService(Context context) { super(context); - mLocalDevices = readDeviceTypes(); + mCecLocalDevices = readDeviceTypes(); mSettingsObserver = new SettingsObserver(mHandler); mHdmiCecConfig = new HdmiCecConfig(context); } @@ -666,7 +669,7 @@ public class HdmiControlService extends SystemService { public void onChange(String setting) { @HdmiControlManager.HdmiCecControl int enabled = mHdmiCecConfig.getIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED); - setControlEnabled(enabled); + setCecEnabled(enabled); } }, mServiceThreadExecutor); mHdmiCecConfig.registerChangeListener(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, @@ -693,6 +696,14 @@ public class HdmiControlService extends SystemService { } } }, mServiceThreadExecutor); + mHdmiCecConfig.registerChangeListener(HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, + new HdmiCecConfig.SettingChangeListener() { + @Override + public void onChange(String setting) { + setSoundbarMode(mHdmiCecConfig.getIntValue( + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE)); + } + }, mServiceThreadExecutor); mHdmiCecConfig.registerChangeListener( HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, new HdmiCecConfig.SettingChangeListener() { @@ -747,7 +758,7 @@ public class HdmiControlService extends SystemService { mPowerStatusController.setPowerStatus(HdmiControlManager.POWER_STATUS_ON); // Start all actions that were queued because the device was in standby if (mAddressAllocated) { - for (HdmiCecLocalDevice localDevice : getAllLocalDevices()) { + for (HdmiCecLocalDevice localDevice : getAllCecLocalDevices()) { localDevice.startQueuedActions(); } } @@ -770,6 +781,11 @@ public class HdmiControlService extends SystemService { } @VisibleForTesting + void setAudioManager(AudioManager audioManager) { + mAudioManager = audioManager; + } + + @VisibleForTesting void setCecController(HdmiCecController cecController) { mCecController = cecController; } @@ -847,6 +863,47 @@ public class HdmiControlService extends SystemService { } /** + * Triggers the address allocation that states the presence of a local device audio system in + * the network. + */ + @VisibleForTesting + public void setSoundbarMode(final int settingValue) { + HdmiCecLocalDevicePlayback playback = playback(); + HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); + if (playback == null) { + Slog.w(TAG, "Device type not compatible to change soundbar mode."); + return; + } + if (!SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) { + Slog.w(TAG, "Device type doesn't support ARC."); + return; + } + if (settingValue == SOUNDBAR_MODE_DISABLED && audioSystem != null) { + if (audioSystem.isArcEnabled()) { + audioSystem.addAndStartAction(new ArcTerminationActionFromAvr(audioSystem)); + } + if (isSystemAudioActivated()) { + audioSystem.terminateSystemAudioMode(); + } + } + mAddressAllocated = false; + initializeCecLocalDevices(INITIATED_BY_SOUNDBAR_MODE); + } + + /** + * Checks if the Device Discovery is handled by the local device playback. + * See {@link HdmiCecLocalDeviceAudioSystem#launchDeviceDiscovery}. + */ + public boolean isDeviceDiscoveryHandledByPlayback() { + HdmiCecLocalDevicePlayback playback = playback(); + if (playback != null && (playback.hasAction(DeviceDiscoveryAction.class) + || playback.hasAction(HotplugDetectionAction.class))) { + return true; + } + return false; + } + + /** * Called when the initialization of local devices is complete. */ private void onInitializeCecComplete(int initiatedBy) { @@ -866,7 +923,7 @@ public class HdmiControlService extends SystemService { break; case INITIATED_BY_SCREEN_ON: reason = HdmiControlManager.CONTROL_STATE_CHANGED_REASON_WAKEUP; - final List<HdmiCecLocalDevice> devices = getAllLocalDevices(); + final List<HdmiCecLocalDevice> devices = getAllCecLocalDevices(); for (HdmiCecLocalDevice device : devices) { device.onInitializeCecComplete(initiatedBy); } @@ -990,15 +1047,33 @@ public class HdmiControlService extends SystemService { mCecController.enableSystemCecControl(true); mCecController.setLanguage(mMenuLanguage); - initializeLocalDevices(initiatedBy); + initializeCecLocalDevices(initiatedBy); } + /** + * If the Soundbar mode is turned on, adds the local device type audio system in the list of + * local devices types. This method is called when the local devices are initialized such that + * the list of local devices is in sync with the Soundbar mode setting. + * @return the list of integer device types + */ @ServiceThreadOnly - private void initializeLocalDevices(final int initiatedBy) { + private List<Integer> getCecLocalDeviceTypes() { + ArrayList<Integer> allLocalDeviceTypes = new ArrayList<>(mCecLocalDevices); + if (mHdmiCecConfig.getIntValue(HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE) + == SOUNDBAR_MODE_ENABLED + && !allLocalDeviceTypes.contains(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) + && SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) { + allLocalDeviceTypes.add(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); + } + return allLocalDeviceTypes; + } + + @ServiceThreadOnly + private void initializeCecLocalDevices(final int initiatedBy) { assertRunOnServiceThread(); // A container for [Device type, Local device info]. ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); - for (int type : mLocalDevices) { + for (int type : getCecLocalDeviceTypes()) { HdmiCecLocalDevice localDevice = mHdmiCecNetwork.getLocalDevice(type); if (localDevice == null) { localDevice = HdmiCecLocalDevice.create(this, type); @@ -1008,7 +1083,7 @@ public class HdmiControlService extends SystemService { } // It's now safe to flush existing local devices from mCecController since they were // already moved to 'localDevices'. - clearLocalDevices(); + clearCecLocalDevices(); allocateLogicalAddress(localDevices, initiatedBy); } @@ -1051,9 +1126,10 @@ public class HdmiControlService extends SystemService { // Address allocation completed for all devices. Notify each device. if (allocatingDevices.size() == ++finished[0]) { - if (initiatedBy != INITIATED_BY_HOTPLUG) { - // In case of the hotplug we don't call - // onInitializeCecComplete() + if (initiatedBy != INITIATED_BY_HOTPLUG + && initiatedBy != INITIATED_BY_SOUNDBAR_MODE) { + // In case of the hotplug or soundbar mode setting toggle + // we don't call onInitializeCecComplete() // since we reallocate the logical address only. onInitializeCecComplete(initiatedBy); } @@ -1331,7 +1407,7 @@ public class HdmiControlService extends SystemService { * Returns whether the source address of a message is a local logical address. */ private boolean sourceAddressIsLocal(HdmiCecMessage message) { - for (HdmiCecLocalDevice device : getAllLocalDevices()) { + for (HdmiCecLocalDevice device : getAllCecLocalDevices()) { if (message.getSource() == device.getDeviceInfo().getLogicalAddress() && message.getSource() != Constants.ADDR_UNREGISTERED) { HdmiLogger.warning( @@ -1413,7 +1489,7 @@ public class HdmiControlService extends SystemService { if (connected && !isTvDevice() && getPortInfo(portId).getType() == HdmiPortInfo.PORT_OUTPUT) { ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); - for (int type : mLocalDevices) { + for (int type : getCecLocalDeviceTypes()) { HdmiCecLocalDevice localDevice = mHdmiCecNetwork.getLocalDevice(type); if (localDevice == null) { localDevice = HdmiCecLocalDevice.create(this, type); @@ -1461,7 +1537,7 @@ public class HdmiControlService extends SystemService { return strategy | iterationStrategy; } - List<HdmiCecLocalDevice> getAllLocalDevices() { + List<HdmiCecLocalDevice> getAllCecLocalDevices() { assertRunOnServiceThread(); return mHdmiCecNetwork.getLocalDeviceList(); } @@ -1484,7 +1560,7 @@ public class HdmiControlService extends SystemService { if (physicalAddress == getPhysicalAddress()) { return; } - for (HdmiCecLocalDevice device : getAllLocalDevices()) { + for (HdmiCecLocalDevice device : getAllCecLocalDevices()) { if (device.getDeviceInfo().getLogicalAddress() == logicalAddress) { HdmiLogger.debug("allocate logical address for " + device.getDeviceInfo()); ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); @@ -1555,7 +1631,7 @@ public class HdmiControlService extends SystemService { // Set the display name in HdmiDeviceInfo of the current devices to content provided by // Global.DEVICE_NAME. Only set and broadcast if the new name is different. private void setDisplayName(String newDisplayName) { - for (HdmiCecLocalDevice device : getAllLocalDevices()) { + for (HdmiCecLocalDevice device : getAllCecLocalDevices()) { HdmiDeviceInfo deviceInfo = device.getDeviceInfo(); if (deviceInfo.getDisplayName().equals(newDisplayName)) { continue; @@ -1816,10 +1892,10 @@ public class HdmiControlService extends SystemService { @Override public int[] getSupportedTypes() { initBinderCall(); - // mLocalDevices is an unmodifiable list - no lock necesary. - int[] localDevices = new int[mLocalDevices.size()]; + // mCecLocalDevices is an unmodifiable list - no lock necessary. + int[] localDevices = new int[mCecLocalDevices.size()]; for (int i = 0; i < localDevices.length; ++i) { - localDevices[i] = mLocalDevices.get(i); + localDevices[i] = mCecLocalDevices.get(i); } return localDevices; } @@ -2379,7 +2455,7 @@ public class HdmiControlService extends SystemService { runOnServiceThread(new Runnable() { @Override public void run() { - if (!isControlEnabled()) { + if (!isCecControlEnabled()) { Slog.w(TAG, "Hdmi control is disabled."); return ; } @@ -3172,15 +3248,15 @@ public class HdmiControlService extends SystemService { } boolean isTvDevice() { - return mLocalDevices.contains(HdmiDeviceInfo.DEVICE_TV); + return mCecLocalDevices.contains(HdmiDeviceInfo.DEVICE_TV); } boolean isAudioSystemDevice() { - return mLocalDevices.contains(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); + return mCecLocalDevices.contains(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); } boolean isPlaybackDevice() { - return mLocalDevices.contains(HdmiDeviceInfo.DEVICE_PLAYBACK); + return mCecLocalDevices.contains(HdmiDeviceInfo.DEVICE_PLAYBACK); } boolean isSwitchDevice() { @@ -3217,7 +3293,7 @@ public class HdmiControlService extends SystemService { return mAudioDeviceVolumeManager; } - boolean isControlEnabled() { + boolean isCecControlEnabled() { synchronized (mLock) { return mHdmiControlEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; } @@ -3329,7 +3405,7 @@ public class HdmiControlService extends SystemService { invokeVendorCommandListenersOnControlStateChanged(false, HdmiControlManager.CONTROL_STATE_CHANGED_REASON_STANDBY); - final List<HdmiCecLocalDevice> devices = getAllLocalDevices(); + final List<HdmiCecLocalDevice> devices = getAllCecLocalDevices(); if (!isStandbyMessageReceived() && !canGoToStandby()) { mPowerStatusController.setPowerStatus(HdmiControlManager.POWER_STATUS_STANDBY); @@ -3339,7 +3415,7 @@ public class HdmiControlService extends SystemService { return; } - disableDevices(new PendingActionClearedCallback() { + disableCecLocalDevices(new PendingActionClearedCallback() { @Override public void onCleared(HdmiCecLocalDevice device) { Slog.v(TAG, "On standby-action cleared:" + device.mDeviceType); @@ -3387,7 +3463,7 @@ public class HdmiControlService extends SystemService { return mMenuLanguage; } - private void disableDevices(PendingActionClearedCallback callback) { + private void disableCecLocalDevices(PendingActionClearedCallback callback) { if (mCecController != null) { for (HdmiCecLocalDevice device : mHdmiCecNetwork.getLocalDeviceList()) { device.disableDevice(mStandbyMessageReceived, callback); @@ -3397,7 +3473,8 @@ public class HdmiControlService extends SystemService { } @ServiceThreadOnly - private void clearLocalDevices() { + @VisibleForTesting + protected void clearCecLocalDevices() { assertRunOnServiceThread(); if (mCecController == null) { return; @@ -3573,7 +3650,7 @@ public class HdmiControlService extends SystemService { } @ServiceThreadOnly - void setControlEnabled(@HdmiControlManager.HdmiCecControl int enabled) { + void setCecEnabled(@HdmiControlManager.HdmiCecControl int enabled) { assertRunOnServiceThread(); synchronized (mLock) { @@ -3581,7 +3658,7 @@ public class HdmiControlService extends SystemService { } if (enabled == HDMI_CEC_CONTROL_ENABLED) { - enableHdmiControlService(); + onEnableCec(); setHdmiCecVolumeControlEnabledInternal(getHdmiCecConfig().getIntValue( HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)); return; @@ -3596,7 +3673,7 @@ public class HdmiControlService extends SystemService { runOnServiceThread(new Runnable() { @Override public void run() { - disableHdmiControlService(); + onDisableCec(); } }); announceHdmiControlStatusChange(enabled); @@ -3605,7 +3682,7 @@ public class HdmiControlService extends SystemService { } @ServiceThreadOnly - private void enableHdmiControlService() { + private void onEnableCec() { mCecController.enableCec(true); mCecController.enableSystemCecControl(true); mMhlController.setOption(OPTION_MHL_ENABLE, ENABLED); @@ -3614,8 +3691,8 @@ public class HdmiControlService extends SystemService { } @ServiceThreadOnly - private void disableHdmiControlService() { - disableDevices( + private void onDisableCec() { + disableCecLocalDevices( new PendingActionClearedCallback() { @Override public void onCleared(HdmiCecLocalDevice device) { @@ -3627,7 +3704,7 @@ public class HdmiControlService extends SystemService { mCecController.enableCec(false); mCecController.enableSystemCecControl(false); mMhlController.setOption(OPTION_MHL_ENABLE, DISABLED); - clearLocalDevices(); + clearCecLocalDevices(); } }); } @@ -3671,7 +3748,7 @@ public class HdmiControlService extends SystemService { // If the current device is a source device, check if the current Active Source matches // the local device info. - for (HdmiCecLocalDevice device : getAllLocalDevices()) { + for (HdmiCecLocalDevice device : getAllCecLocalDevices()) { boolean deviceIsActiveSource = logicalAddress == device.getDeviceInfo().getLogicalAddress() && physicalAddress == getPhysicalAddress(); diff --git a/services/core/java/com/android/server/input/BatteryController.java b/services/core/java/com/android/server/input/BatteryController.java index c83fa2d3942c..c99a7a0de79c 100644 --- a/services/core/java/com/android/server/input/BatteryController.java +++ b/services/core/java/com/android/server/input/BatteryController.java @@ -19,7 +19,13 @@ package com.android.server.input; import android.annotation.BinderThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.hardware.BatteryState; import android.hardware.input.IInputDeviceBatteryListener; import android.hardware.input.IInputDeviceBatteryState; @@ -46,6 +52,7 @@ import java.util.Arrays; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; /** @@ -74,6 +81,7 @@ final class BatteryController { private final NativeInputManagerService mNative; private final Handler mHandler; private final UEventManager mUEventManager; + private final BluetoothBatteryManager mBluetoothBatteryManager; // Maps a pid to the registered listener record for that process. There can only be one battery // listener per process. @@ -88,18 +96,23 @@ final class BatteryController { private boolean mIsPolling = false; @GuardedBy("mLock") private boolean mIsInteractive = true; + @Nullable + @GuardedBy("mLock") + private BluetoothBatteryManager.BluetoothBatteryListener mBluetoothBatteryListener; BatteryController(Context context, NativeInputManagerService nativeService, Looper looper) { - this(context, nativeService, looper, new UEventManager() {}); + this(context, nativeService, looper, new UEventManager() {}, + new LocalBluetoothBatteryManager(context)); } @VisibleForTesting BatteryController(Context context, NativeInputManagerService nativeService, Looper looper, - UEventManager uEventManager) { + UEventManager uEventManager, BluetoothBatteryManager bbm) { mContext = context; mNative = nativeService; mHandler = new Handler(looper); mUEventManager = uEventManager; + mBluetoothBatteryManager = bbm; } public void systemRunning() { @@ -150,6 +163,7 @@ final class BatteryController { // This is the first listener that is monitoring this device. monitor = new DeviceMonitor(deviceId); mDeviceMonitors.put(deviceId, monitor); + updateBluetoothMonitoring(); } if (DEBUG) { @@ -202,25 +216,39 @@ final class BatteryController { mHandler.postDelayed(this::handlePollEvent, delayStart ? POLLING_PERIOD_MILLIS : 0); } - private String getInputDeviceName(int deviceId) { + private <R> R processInputDevice(int deviceId, R defaultValue, Function<InputDevice, R> func) { final InputDevice device = Objects.requireNonNull(mContext.getSystemService(InputManager.class)) .getInputDevice(deviceId); - return device != null ? device.getName() : "<none>"; + return device == null ? defaultValue : func.apply(device); + } + + private String getInputDeviceName(int deviceId) { + return processInputDevice(deviceId, "<none>" /*defaultValue*/, InputDevice::getName); } private boolean hasBattery(int deviceId) { - final InputDevice device = - Objects.requireNonNull(mContext.getSystemService(InputManager.class)) - .getInputDevice(deviceId); - return device != null && device.hasBattery(); + return processInputDevice(deviceId, false /*defaultValue*/, InputDevice::hasBattery); } private boolean isUsiDevice(int deviceId) { - final InputDevice device = - Objects.requireNonNull(mContext.getSystemService(InputManager.class)) - .getInputDevice(deviceId); - return device != null && device.supportsUsi(); + return processInputDevice(deviceId, false /*defaultValue*/, InputDevice::supportsUsi); + } + + @Nullable + private BluetoothDevice getBluetoothDevice(int inputDeviceId) { + return getBluetoothDevice(mContext, + processInputDevice(inputDeviceId, null /*defaultValue*/, + InputDevice::getBluetoothAddress)); + } + + @Nullable + private static BluetoothDevice getBluetoothDevice(Context context, String address) { + if (address == null) return null; + final BluetoothAdapter adapter = + Objects.requireNonNull(context.getSystemService(BluetoothManager.class)) + .getAdapter(); + return adapter.getRemoteDevice(address); } @GuardedBy("mLock") @@ -350,6 +378,17 @@ final class BatteryController { } } + private void handleBluetoothBatteryLevelChange(long eventTime, String address) { + synchronized (mLock) { + final DeviceMonitor monitor = findIf(mDeviceMonitors, (m) -> + (m.mBluetoothDevice != null + && address.equals(m.mBluetoothDevice.getAddress()))); + if (monitor != null) { + monitor.onBluetoothBatteryChanged(eventTime); + } + } + } + /** Gets the current battery state of an input device. */ public IInputDeviceBatteryState getBatteryState(int deviceId) { synchronized (mLock) { @@ -475,17 +514,52 @@ final class BatteryController { isPresent ? mNative.getBatteryCapacity(deviceId) / 100.f : Float.NaN); } + // Queries the battery state of an input device from Bluetooth. + private State queryBatteryStateFromBluetooth(int deviceId, long updateTime, + @NonNull BluetoothDevice bluetoothDevice) { + final int level = mBluetoothBatteryManager.getBatteryLevel(bluetoothDevice.getAddress()); + if (level == BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF + || level == BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { + return new State(deviceId); + } + return new State(deviceId, updateTime, true /*isPresent*/, BatteryState.STATUS_UNKNOWN, + level / 100.f); + } + + private void updateBluetoothMonitoring() { + synchronized (mLock) { + if (anyOf(mDeviceMonitors, (m) -> m.mBluetoothDevice != null)) { + // At least one input device being monitored is connected over Bluetooth. + if (mBluetoothBatteryListener == null) { + if (DEBUG) Slog.d(TAG, "Registering bluetooth battery listener"); + mBluetoothBatteryListener = this::handleBluetoothBatteryLevelChange; + mBluetoothBatteryManager.addListener(mBluetoothBatteryListener); + } + } else if (mBluetoothBatteryListener != null) { + // No Bluetooth input devices are monitored, so remove the registered listener. + if (DEBUG) Slog.d(TAG, "Unregistering bluetooth battery listener"); + mBluetoothBatteryManager.removeListener(mBluetoothBatteryListener); + mBluetoothBatteryListener = null; + } + } + } + // Holds the state of an InputDevice for which battery changes are currently being monitored. private class DeviceMonitor { protected final State mState; // Represents whether the input device has a sysfs battery node. protected boolean mHasBattery = false; + protected final State mBluetoothState; + @Nullable + private BluetoothDevice mBluetoothDevice; + @Nullable private UEventBatteryListener mUEventBatteryListener; DeviceMonitor(int deviceId) { mState = new State(deviceId); + mBluetoothState = new State(deviceId); // Load the initial battery state and start monitoring. final long eventTime = SystemClock.uptimeMillis(); @@ -506,18 +580,31 @@ final class BatteryController { } private void configureDeviceMonitor(long eventTime) { + final int deviceId = mState.deviceId; if (mHasBattery != hasBattery(mState.deviceId)) { mHasBattery = !mHasBattery; if (mHasBattery) { - startMonitoring(); + startNativeMonitoring(); } else { - stopMonitoring(); + stopNativeMonitoring(); } updateBatteryStateFromNative(eventTime); } + + final BluetoothDevice bluetoothDevice = getBluetoothDevice(deviceId); + if (!Objects.equals(mBluetoothDevice, bluetoothDevice)) { + if (DEBUG) { + Slog.d(TAG, "Bluetooth device " + + ((bluetoothDevice != null) ? "is" : "is not") + + " now present for deviceId " + deviceId); + } + mBluetoothDevice = bluetoothDevice; + updateBluetoothMonitoring(); + updateBatteryStateFromBluetooth(eventTime); + } } - private void startMonitoring() { + private void startNativeMonitoring() { final String batteryPath = mNative.getBatteryDevicePath(mState.deviceId); if (batteryPath == null) { return; @@ -538,7 +625,7 @@ final class BatteryController { return path.startsWith("/sys") ? path.substring(4) : path; } - private void stopMonitoring() { + private void stopNativeMonitoring() { if (mUEventBatteryListener != null) { mUEventManager.removeListener(mUEventBatteryListener); mUEventBatteryListener = null; @@ -547,7 +634,9 @@ final class BatteryController { // This must be called when the device is no longer being monitored. public void onMonitorDestroy() { - stopMonitoring(); + stopNativeMonitoring(); + mBluetoothDevice = null; + updateBluetoothMonitoring(); } protected void updateBatteryStateFromNative(long eventTime) { @@ -555,6 +644,13 @@ final class BatteryController { queryBatteryStateFromNative(mState.deviceId, eventTime, mHasBattery)); } + protected void updateBatteryStateFromBluetooth(long eventTime) { + final State bluetoothState = mBluetoothDevice == null ? new State(mState.deviceId) + : queryBatteryStateFromBluetooth(mState.deviceId, eventTime, + mBluetoothDevice); + mBluetoothState.updateIfChanged(bluetoothState); + } + public void onPoll(long eventTime) { processChangesAndNotify(eventTime, this::updateBatteryStateFromNative); } @@ -563,6 +659,10 @@ final class BatteryController { processChangesAndNotify(eventTime, this::updateBatteryStateFromNative); } + public void onBluetoothBatteryChanged(long eventTime) { + processChangesAndNotify(eventTime, this::updateBatteryStateFromBluetooth); + } + public boolean requiresPolling() { return true; } @@ -577,6 +677,10 @@ final class BatteryController { // Returns the current battery state that can be used to notify listeners BatteryController. public State getBatteryStateForReporting() { + // Give precedence to the Bluetooth battery state if it's present. + if (mBluetoothState.isPresent) { + return new State(mBluetoothState); + } return new State(mState); } @@ -585,7 +689,8 @@ final class BatteryController { return "DeviceId=" + mState.deviceId + ", Name='" + getInputDeviceName(mState.deviceId) + "'" + ", NativeBattery=" + mState - + ", UEventListener=" + (mUEventBatteryListener != null ? "added" : "none"); + + ", UEventListener=" + (mUEventBatteryListener != null ? "added" : "none") + + ", BluetoothBattery=" + mBluetoothState; } } @@ -670,6 +775,10 @@ final class BatteryController { @Override public State getBatteryStateForReporting() { + // Give precedence to the Bluetooth battery state if it's present. + if (mBluetoothState.isPresent) { + return new State(mBluetoothState); + } return mValidityTimeoutCallback != null ? new State(mState) : new State(mState.deviceId); } @@ -729,6 +838,82 @@ final class BatteryController { } } + // An interface used to change the API of adding a bluetooth battery listener to a more + // test-friendly format. + @VisibleForTesting + interface BluetoothBatteryManager { + @VisibleForTesting + interface BluetoothBatteryListener { + void onBluetoothBatteryChanged(long eventTime, String address); + } + void addListener(BluetoothBatteryListener listener); + void removeListener(BluetoothBatteryListener listener); + int getBatteryLevel(String address); + } + + private static class LocalBluetoothBatteryManager implements BluetoothBatteryManager { + private final Context mContext; + @Nullable + @GuardedBy("mBroadcastReceiver") + private BluetoothBatteryListener mRegisteredListener; + @GuardedBy("mBroadcastReceiver") + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED.equals(intent.getAction())) { + return; + } + final BluetoothDevice bluetoothDevice = intent.getParcelableExtra( + BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class); + if (bluetoothDevice == null) { + return; + } + // We do not use the EXTRA_LEVEL value. Instead, the battery level will be queried + // from BluetoothDevice later so that we use a single source for the battery level. + synchronized (mBroadcastReceiver) { + if (mRegisteredListener != null) { + final long eventTime = SystemClock.uptimeMillis(); + mRegisteredListener.onBluetoothBatteryChanged( + eventTime, bluetoothDevice.getAddress()); + } + } + } + }; + + LocalBluetoothBatteryManager(Context context) { + mContext = context; + } + + @Override + public void addListener(BluetoothBatteryListener listener) { + synchronized (mBroadcastReceiver) { + if (mRegisteredListener != null) { + throw new IllegalStateException( + "Only one bluetooth battery listener can be registered at once."); + } + mRegisteredListener = listener; + mContext.registerReceiver(mBroadcastReceiver, + new IntentFilter(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED)); + } + } + + @Override + public void removeListener(BluetoothBatteryListener listener) { + synchronized (mBroadcastReceiver) { + if (!listener.equals(mRegisteredListener)) { + throw new IllegalStateException("Listener is not registered."); + } + mRegisteredListener = null; + mContext.unregisterReceiver(mBroadcastReceiver); + } + } + + @Override + public int getBatteryLevel(String address) { + return getBluetoothDevice(mContext, address).getBatteryLevel(); + } + } + // Helper class that adds copying and printing functionality to IInputDeviceBatteryState. private static class State extends IInputDeviceBatteryState { @@ -792,11 +977,17 @@ final class BatteryController { // Check if any value in an ArrayMap matches the predicate in an optimized way. private static <K, V> boolean anyOf(ArrayMap<K, V> arrayMap, Predicate<V> test) { + return findIf(arrayMap, test) != null; + } + + // Find the first value in an ArrayMap that matches the predicate in an optimized way. + private static <K, V> V findIf(ArrayMap<K, V> arrayMap, Predicate<V> test) { for (int i = 0; i < arrayMap.size(); i++) { - if (test.test(arrayMap.valueAt(i))) { - return true; + final V value = arrayMap.valueAt(i); + if (test.test(value)) { + return value; } } - return false; + return null; } } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index c20d8806412d..199519c19785 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -25,25 +25,13 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.content.res.Resources.NotFoundException; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; import android.database.ContentObserver; import android.graphics.PointF; import android.hardware.SensorPrivacyManager; @@ -66,7 +54,6 @@ import android.hardware.lights.Light; import android.hardware.lights.LightState; import android.media.AudioManager; import android.os.Binder; -import android.os.Bundle; import android.os.CombinedVibration; import android.os.Environment; import android.os.Handler; @@ -75,7 +62,6 @@ import android.os.IInputConstants; import android.os.IVibratorStateListener; import android.os.InputEventInjectionResult; import android.os.InputEventInjectionSync; -import android.os.LocaleList; import android.os.Looper; import android.os.Message; import android.os.Process; @@ -113,18 +99,14 @@ import android.view.SurfaceControl; import android.view.VerifiedInputEvent; import android.view.ViewConfiguration; import android.view.inputmethod.InputMethodSubtype; -import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.InputMethodSubtypeHandle; -import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.SomeArgs; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; -import com.android.internal.util.XmlUtils; import com.android.server.DisplayThread; import com.android.server.LocalServices; import com.android.server.Watchdog; @@ -132,7 +114,6 @@ import com.android.server.input.InputManagerInternal.LidSwitchCallback; import com.android.server.policy.WindowManagerPolicy; import libcore.io.IoUtils; -import libcore.io.Streams; import java.io.File; import java.io.FileDescriptor; @@ -141,15 +122,11 @@ import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.OptionalInt; @@ -171,12 +148,9 @@ public class InputManagerService extends IInputManager.Stub private static final String VELOCITYTRACKER_STRATEGY_PROPERTY = "velocitytracker_strategy"; private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1; - private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 2; - private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3; - private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4; - private static final int MSG_RELOAD_DEVICE_ALIASES = 5; - private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 6; - private static final int MSG_POINTER_DISPLAY_ID_CHANGED = 7; + private static final int MSG_RELOAD_DEVICE_ALIASES = 2; + private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 3; + private static final int MSG_POINTER_DISPLAY_ID_CHANGED = 4; private static final int DEFAULT_VIBRATION_MAGNITUDE = 192; private static final AdditionalDisplayInputProperties @@ -195,7 +169,6 @@ public class InputManagerService extends IInputManager.Stub private WindowManagerCallbacks mWindowManagerCallbacks; private WiredAccessoryCallbacks mWiredAccessoryCallbacks; private boolean mSystemReady; - private NotificationManager mNotificationManager; private final Object mTabletModeLock = new Object(); // List of currently registered tablet mode changed listeners by process id @@ -229,10 +202,6 @@ public class InputManagerService extends IInputManager.Stub new SparseArray<>(); private final ArrayList<InputDevicesChangedListenerRecord> mTempInputDevicesChangedListenersToNotify = new ArrayList<>(); // handler thread only - private final ArrayList<InputDevice> mTempFullKeyboards = - new ArrayList<>(); // handler thread only - private boolean mKeyboardLayoutNotificationShown; - private Toast mSwitchedKeyboardLayoutToast; // State for vibrator tokens. private final Object mVibratorLock = new Object(); @@ -315,6 +284,9 @@ public class InputManagerService extends IInputManager.Stub @GuardedBy("mInputMonitors") final Map<IBinder, GestureMonitorSpyWindow> mInputMonitors = new HashMap<>(); + // Manages Keyboard layouts for Physical keyboards + private final KeyboardLayoutManager mKeyboardLayoutManager; + // Manages battery state for input devices. private final BatteryController mBatteryController; @@ -430,6 +402,8 @@ public class InputManagerService extends IInputManager.Stub mContext = injector.getContext(); mHandler = new InputManagerHandler(injector.getLooper()); mNative = injector.getNativeService(this); + mKeyboardLayoutManager = new KeyboardLayoutManager(mContext, mNative, mDataStore, + injector.getLooper()); mBatteryController = new BatteryController(mContext, mNative, injector.getLooper()); mKeyboardBacklightController = new KeyboardBacklightController(mContext, mNative, mDataStore, injector.getLooper()); @@ -518,8 +492,6 @@ public class InputManagerService extends IInputManager.Stub if (DEBUG) { Slog.d(TAG, "System ready."); } - mNotificationManager = (NotificationManager)mContext.getSystemService( - Context.NOTIFICATION_SERVICE); synchronized (mLidSwitchLock) { mSystemReady = true; @@ -546,19 +518,7 @@ public class InputManagerService extends IInputManager.Stub setSensorPrivacy(Sensors.CAMERA, true); } - IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); - filter.addAction(Intent.ACTION_PACKAGE_REMOVED); - filter.addAction(Intent.ACTION_PACKAGE_CHANGED); - filter.addAction(Intent.ACTION_PACKAGE_REPLACED); - filter.addDataScheme("package"); - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - updateKeyboardLayouts(); - } - }, filter, null, mHandler); - - filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED); + IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -567,23 +527,16 @@ public class InputManagerService extends IInputManager.Stub }, filter, null, mHandler); mHandler.sendEmptyMessage(MSG_RELOAD_DEVICE_ALIASES); - mHandler.sendEmptyMessage(MSG_UPDATE_KEYBOARD_LAYOUTS); if (mWiredAccessoryCallbacks != null) { mWiredAccessoryCallbacks.systemReady(); } + mKeyboardLayoutManager.systemRunning(); mBatteryController.systemRunning(); mKeyboardBacklightController.systemRunning(); } - private void reloadKeyboardLayouts() { - if (DEBUG) { - Slog.d(TAG, "Reloading keyboard layouts."); - } - mNative.reloadKeyboardLayouts(); - } - private void reloadDeviceAliases() { if (DEBUG) { Slog.d(TAG, "Reloading device names."); @@ -1044,9 +997,7 @@ public class InputManagerService extends IInputManager.Stub // Must be called on handler. private void deliverInputDevicesChanged(InputDevice[] oldInputDevices) { // Scan for changes. - int numFullKeyboardsAdded = 0; mTempInputDevicesChangedListenersToNotify.clear(); - mTempFullKeyboards.clear(); final int numListeners; final int[] deviceIdAndGeneration; synchronized (mInputDevicesLock) { @@ -1071,15 +1022,6 @@ public class InputManagerService extends IInputManager.Stub Log.d(TAG, "device " + inputDevice.getId() + " generation " + inputDevice.getGeneration()); } - - if (!inputDevice.isVirtual() && inputDevice.isFullKeyboard()) { - if (!containsInputDeviceWithDescriptor(oldInputDevices, - inputDevice.getDescriptor())) { - mTempFullKeyboards.add(numFullKeyboardsAdded++, inputDevice); - } else { - mTempFullKeyboards.add(inputDevice); - } - } } } @@ -1089,119 +1031,6 @@ public class InputManagerService extends IInputManager.Stub deviceIdAndGeneration); } mTempInputDevicesChangedListenersToNotify.clear(); - - // Check for missing keyboard layouts. - List<InputDevice> keyboardsMissingLayout = new ArrayList<>(); - final int numFullKeyboards = mTempFullKeyboards.size(); - synchronized (mDataStore) { - for (int i = 0; i < numFullKeyboards; i++) { - final InputDevice inputDevice = mTempFullKeyboards.get(i); - String layout = - getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier()); - if (layout == null) { - layout = getDefaultKeyboardLayout(inputDevice); - if (layout != null) { - setCurrentKeyboardLayoutForInputDevice( - inputDevice.getIdentifier(), layout); - } - } - if (layout == null) { - keyboardsMissingLayout.add(inputDevice); - } - } - } - - if (mNotificationManager != null) { - if (!keyboardsMissingLayout.isEmpty()) { - if (keyboardsMissingLayout.size() > 1) { - // We have more than one keyboard missing a layout, so drop the - // user at the generic input methods page so they can pick which - // one to set. - showMissingKeyboardLayoutNotification(null); - } else { - showMissingKeyboardLayoutNotification(keyboardsMissingLayout.get(0)); - } - } else if (mKeyboardLayoutNotificationShown) { - hideMissingKeyboardLayoutNotification(); - } - } - mTempFullKeyboards.clear(); - } - - private String getDefaultKeyboardLayout(final InputDevice d) { - final Locale systemLocale = mContext.getResources().getConfiguration().locale; - // If our locale doesn't have a language for some reason, then we don't really have a - // reasonable default. - if (TextUtils.isEmpty(systemLocale.getLanguage())) { - return null; - } - final List<KeyboardLayout> layouts = new ArrayList<>(); - visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> { - // Only select a default when we know the layout is appropriate. For now, this - // means it's a custom layout for a specific keyboard. - if (layout.getVendorId() != d.getVendorId() - || layout.getProductId() != d.getProductId()) { - return; - } - final LocaleList locales = layout.getLocales(); - final int numLocales = locales.size(); - for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) { - if (isCompatibleLocale(systemLocale, locales.get(localeIndex))) { - layouts.add(layout); - break; - } - } - }); - - if (layouts.isEmpty()) { - return null; - } - - // First sort so that ones with higher priority are listed at the top - Collections.sort(layouts); - // Next we want to try to find an exact match of language, country and variant. - final int N = layouts.size(); - for (int i = 0; i < N; i++) { - KeyboardLayout layout = layouts.get(i); - final LocaleList locales = layout.getLocales(); - final int numLocales = locales.size(); - for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) { - final Locale locale = locales.get(localeIndex); - if (locale.getCountry().equals(systemLocale.getCountry()) - && locale.getVariant().equals(systemLocale.getVariant())) { - return layout.getDescriptor(); - } - } - } - // Then try an exact match of language and country - for (int i = 0; i < N; i++) { - KeyboardLayout layout = layouts.get(i); - final LocaleList locales = layout.getLocales(); - final int numLocales = locales.size(); - for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) { - final Locale locale = locales.get(localeIndex); - if (locale.getCountry().equals(systemLocale.getCountry())) { - return layout.getDescriptor(); - } - } - } - - // Give up and just use the highest priority layout with matching language - return layouts.get(0).getDescriptor(); - } - - private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) { - // Different languages are never compatible - if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) { - return false; - } - // If both the system and the keyboard layout have a country specifier, they must be equal. - if (!TextUtils.isEmpty(systemLocale.getCountry()) - && !TextUtils.isEmpty(keyboardLocale.getCountry()) - && !systemLocale.getCountry().equals(keyboardLocale.getCountry())) { - return false; - } - return true; } @Override // Binder call & native callback @@ -1302,446 +1131,61 @@ public class InputManagerService extends IInputManager.Stub } } - // Must be called on handler. - private void showMissingKeyboardLayoutNotification(InputDevice device) { - if (!mKeyboardLayoutNotificationShown) { - final Intent intent = new Intent(Settings.ACTION_HARD_KEYBOARD_SETTINGS); - if (device != null) { - intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, device.getIdentifier()); - } - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0, - intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); - - Resources r = mContext.getResources(); - Notification notification = - new Notification.Builder(mContext, SystemNotificationChannels.PHYSICAL_KEYBOARD) - .setContentTitle(r.getString( - R.string.select_keyboard_layout_notification_title)) - .setContentText(r.getString( - R.string.select_keyboard_layout_notification_message)) - .setContentIntent(keyboardLayoutIntent) - .setSmallIcon(R.drawable.ic_settings_language) - .setColor(mContext.getColor( - com.android.internal.R.color.system_notification_accent_color)) - .build(); - mNotificationManager.notifyAsUser(null, - SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT, - notification, UserHandle.ALL); - mKeyboardLayoutNotificationShown = true; - } - } - - // Must be called on handler. - private void hideMissingKeyboardLayoutNotification() { - if (mKeyboardLayoutNotificationShown) { - mKeyboardLayoutNotificationShown = false; - mNotificationManager.cancelAsUser(null, - SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT, - UserHandle.ALL); - } - } - - // Must be called on handler. - private void updateKeyboardLayouts() { - // Scan all input devices state for keyboard layouts that have been uninstalled. - final HashSet<String> availableKeyboardLayouts = new HashSet<String>(); - visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> - availableKeyboardLayouts.add(layout.getDescriptor())); - synchronized (mDataStore) { - try { - mDataStore.removeUninstalledKeyboardLayouts(availableKeyboardLayouts); - } finally { - mDataStore.saveIfNeeded(); - } - } - - // Reload keyboard layouts. - reloadKeyboardLayouts(); - } - - private static boolean containsInputDeviceWithDescriptor(InputDevice[] inputDevices, - String descriptor) { - final int numDevices = inputDevices.length; - for (int i = 0; i < numDevices; i++) { - final InputDevice inputDevice = inputDevices[i]; - if (inputDevice.getDescriptor().equals(descriptor)) { - return true; - } - } - return false; - } - @Override // Binder call public KeyboardLayout[] getKeyboardLayouts() { - final ArrayList<KeyboardLayout> list = new ArrayList<>(); - visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> list.add(layout)); - return list.toArray(new KeyboardLayout[list.size()]); + return mKeyboardLayoutManager.getKeyboardLayouts(); } @Override // Binder call public KeyboardLayout[] getKeyboardLayoutsForInputDevice( final InputDeviceIdentifier identifier) { - final String[] enabledLayoutDescriptors = - getEnabledKeyboardLayoutsForInputDevice(identifier); - final ArrayList<KeyboardLayout> enabledLayouts = - new ArrayList<>(enabledLayoutDescriptors.length); - final ArrayList<KeyboardLayout> potentialLayouts = new ArrayList<>(); - visitAllKeyboardLayouts(new KeyboardLayoutVisitor() { - boolean mHasSeenDeviceSpecificLayout; - - @Override - public void visitKeyboardLayout(Resources resources, - int keyboardLayoutResId, KeyboardLayout layout) { - // First check if it's enabled. If the keyboard layout is enabled then we always - // want to return it as a possible layout for the device. - for (String s : enabledLayoutDescriptors) { - if (s != null && s.equals(layout.getDescriptor())) { - enabledLayouts.add(layout); - return; - } - } - // Next find any potential layouts that aren't yet enabled for the device. For - // devices that have special layouts we assume there's a reason that the generic - // layouts don't work for them so we don't want to return them since it's likely - // to result in a poor user experience. - if (layout.getVendorId() == identifier.getVendorId() - && layout.getProductId() == identifier.getProductId()) { - if (!mHasSeenDeviceSpecificLayout) { - mHasSeenDeviceSpecificLayout = true; - potentialLayouts.clear(); - } - potentialLayouts.add(layout); - } else if (layout.getVendorId() == -1 && layout.getProductId() == -1 - && !mHasSeenDeviceSpecificLayout) { - potentialLayouts.add(layout); - } - } - }); - final int enabledLayoutSize = enabledLayouts.size(); - final int potentialLayoutSize = potentialLayouts.size(); - KeyboardLayout[] layouts = new KeyboardLayout[enabledLayoutSize + potentialLayoutSize]; - enabledLayouts.toArray(layouts); - for (int i = 0; i < potentialLayoutSize; i++) { - layouts[enabledLayoutSize + i] = potentialLayouts.get(i); - } - return layouts; + return mKeyboardLayoutManager.getKeyboardLayoutsForInputDevice(identifier); } @Override // Binder call public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { - Objects.requireNonNull(keyboardLayoutDescriptor, - "keyboardLayoutDescriptor must not be null"); - - final KeyboardLayout[] result = new KeyboardLayout[1]; - visitKeyboardLayout(keyboardLayoutDescriptor, - (resources, keyboardLayoutResId, layout) -> result[0] = layout); - if (result[0] == null) { - Slog.w(TAG, "Could not get keyboard layout with descriptor '" - + keyboardLayoutDescriptor + "'."); - } - return result[0]; - } - - private void visitAllKeyboardLayouts(KeyboardLayoutVisitor visitor) { - final PackageManager pm = mContext.getPackageManager(); - Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_LAYOUTS); - for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent, - PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE)) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - final int priority = resolveInfo.priority; - visitKeyboardLayoutsInPackage(pm, activityInfo, null, priority, visitor); - } - } - - private void visitKeyboardLayout(String keyboardLayoutDescriptor, - KeyboardLayoutVisitor visitor) { - KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(keyboardLayoutDescriptor); - if (d != null) { - final PackageManager pm = mContext.getPackageManager(); - try { - ActivityInfo receiver = pm.getReceiverInfo( - new ComponentName(d.packageName, d.receiverName), - PackageManager.GET_META_DATA - | PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); - visitKeyboardLayoutsInPackage(pm, receiver, d.keyboardLayoutName, 0, visitor); - } catch (NameNotFoundException ignored) { - } - } - } - - private void visitKeyboardLayoutsInPackage(PackageManager pm, ActivityInfo receiver, - String keyboardName, int requestedPriority, KeyboardLayoutVisitor visitor) { - Bundle metaData = receiver.metaData; - if (metaData == null) { - return; - } - - int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_LAYOUTS); - if (configResId == 0) { - Slog.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_LAYOUTS - + "' on receiver " + receiver.packageName + "/" + receiver.name); - return; - } - - CharSequence receiverLabel = receiver.loadLabel(pm); - String collection = receiverLabel != null ? receiverLabel.toString() : ""; - int priority; - if ((receiver.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - priority = requestedPriority; - } else { - priority = 0; - } - - try { - Resources resources = pm.getResourcesForApplication(receiver.applicationInfo); - try (XmlResourceParser parser = resources.getXml(configResId)) { - XmlUtils.beginDocument(parser, "keyboard-layouts"); - - while (true) { - XmlUtils.nextElement(parser); - String element = parser.getName(); - if (element == null) { - break; - } - if (element.equals("keyboard-layout")) { - TypedArray a = resources.obtainAttributes( - parser, R.styleable.KeyboardLayout); - try { - String name = a.getString( - R.styleable.KeyboardLayout_name); - String label = a.getString( - R.styleable.KeyboardLayout_label); - int keyboardLayoutResId = a.getResourceId( - R.styleable.KeyboardLayout_keyboardLayout, - 0); - String languageTags = a.getString( - R.styleable.KeyboardLayout_locale); - LocaleList locales = getLocalesFromLanguageTags(languageTags); - int vid = a.getInt( - R.styleable.KeyboardLayout_vendorId, -1); - int pid = a.getInt( - R.styleable.KeyboardLayout_productId, -1); - - if (name == null || label == null || keyboardLayoutResId == 0) { - Slog.w(TAG, "Missing required 'name', 'label' or 'keyboardLayout' " - + "attributes in keyboard layout " - + "resource from receiver " - + receiver.packageName + "/" + receiver.name); - } else { - String descriptor = KeyboardLayoutDescriptor.format( - receiver.packageName, receiver.name, name); - if (keyboardName == null || name.equals(keyboardName)) { - KeyboardLayout layout = new KeyboardLayout( - descriptor, label, collection, priority, - locales, vid, pid); - visitor.visitKeyboardLayout( - resources, keyboardLayoutResId, layout); - } - } - } finally { - a.recycle(); - } - } else { - Slog.w(TAG, "Skipping unrecognized element '" + element - + "' in keyboard layout resource from receiver " - + receiver.packageName + "/" + receiver.name); - } - } - } - } catch (Exception ex) { - Slog.w(TAG, "Could not parse keyboard layout resource from receiver " - + receiver.packageName + "/" + receiver.name, ex); - } - } - - @NonNull - private static LocaleList getLocalesFromLanguageTags(String languageTags) { - if (TextUtils.isEmpty(languageTags)) { - return LocaleList.getEmptyLocaleList(); - } - return LocaleList.forLanguageTags(languageTags.replace('|', ',')); - } - - /** - * Builds a layout descriptor for the vendor/product. This returns the - * descriptor for ids that aren't useful (such as the default 0, 0). - */ - private String getLayoutDescriptor(InputDeviceIdentifier identifier) { - Objects.requireNonNull(identifier, "identifier must not be null"); - Objects.requireNonNull(identifier.getDescriptor(), "descriptor must not be null"); - - if (identifier.getVendorId() == 0 && identifier.getProductId() == 0) { - return identifier.getDescriptor(); - } - return "vendor:" + identifier.getVendorId() + ",product:" + identifier.getProductId(); + return mKeyboardLayoutManager.getKeyboardLayout(keyboardLayoutDescriptor); } @Override // Binder call public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) { - - String key = getLayoutDescriptor(identifier); - synchronized (mDataStore) { - String layout; - // try loading it using the layout descriptor if we have it - layout = mDataStore.getCurrentKeyboardLayout(key); - if (layout == null && !key.equals(identifier.getDescriptor())) { - // if it doesn't exist fall back to the device descriptor - layout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); - } - if (DEBUG) { - Slog.d(TAG, "getCurrentKeyboardLayoutForInputDevice() " - + identifier.toString() + ": " + layout); - } - return layout; - } + return mKeyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(identifier); } + @EnforcePermission(Manifest.permission.SET_KEYBOARD_LAYOUT) @Override // Binder call public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, String keyboardLayoutDescriptor) { - if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, - "setCurrentKeyboardLayoutForInputDevice()")) { - throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); - } - - Objects.requireNonNull(keyboardLayoutDescriptor, - "keyboardLayoutDescriptor must not be null"); - - String key = getLayoutDescriptor(identifier); - synchronized (mDataStore) { - try { - if (mDataStore.setCurrentKeyboardLayout(key, keyboardLayoutDescriptor)) { - if (DEBUG) { - Slog.d(TAG, "setCurrentKeyboardLayoutForInputDevice() " + identifier - + " key: " + key - + " keyboardLayoutDescriptor: " + keyboardLayoutDescriptor); - } - mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); - } - } finally { - mDataStore.saveIfNeeded(); - } - } + super.setCurrentKeyboardLayoutForInputDevice_enforcePermission(); + mKeyboardLayoutManager.setCurrentKeyboardLayoutForInputDevice(identifier, + keyboardLayoutDescriptor); } @Override // Binder call public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) { - String key = getLayoutDescriptor(identifier); - synchronized (mDataStore) { - String[] layouts = mDataStore.getKeyboardLayouts(key); - if ((layouts == null || layouts.length == 0) - && !key.equals(identifier.getDescriptor())) { - layouts = mDataStore.getKeyboardLayouts(identifier.getDescriptor()); - } - return layouts; - } + return mKeyboardLayoutManager.getEnabledKeyboardLayoutsForInputDevice(identifier); } + @EnforcePermission(Manifest.permission.SET_KEYBOARD_LAYOUT) @Override // Binder call public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, String keyboardLayoutDescriptor) { - if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, - "addKeyboardLayoutForInputDevice()")) { - throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); - } - Objects.requireNonNull(keyboardLayoutDescriptor, - "keyboardLayoutDescriptor must not be null"); - - String key = getLayoutDescriptor(identifier); - synchronized (mDataStore) { - try { - String oldLayout = mDataStore.getCurrentKeyboardLayout(key); - if (oldLayout == null && !key.equals(identifier.getDescriptor())) { - oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); - } - if (mDataStore.addKeyboardLayout(key, keyboardLayoutDescriptor) - && !Objects.equals(oldLayout, - mDataStore.getCurrentKeyboardLayout(key))) { - mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); - } - } finally { - mDataStore.saveIfNeeded(); - } - } + super.addKeyboardLayoutForInputDevice_enforcePermission(); + mKeyboardLayoutManager.addKeyboardLayoutForInputDevice(identifier, + keyboardLayoutDescriptor); } + @EnforcePermission(Manifest.permission.SET_KEYBOARD_LAYOUT) @Override // Binder call public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, String keyboardLayoutDescriptor) { - if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, - "removeKeyboardLayoutForInputDevice()")) { - throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); - } - Objects.requireNonNull(keyboardLayoutDescriptor, - "keyboardLayoutDescriptor must not be null"); - - String key = getLayoutDescriptor(identifier); - synchronized (mDataStore) { - try { - String oldLayout = mDataStore.getCurrentKeyboardLayout(key); - if (oldLayout == null && !key.equals(identifier.getDescriptor())) { - oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); - } - boolean removed = mDataStore.removeKeyboardLayout(key, keyboardLayoutDescriptor); - if (!key.equals(identifier.getDescriptor())) { - // We need to remove from both places to ensure it is gone - removed |= mDataStore.removeKeyboardLayout(identifier.getDescriptor(), - keyboardLayoutDescriptor); - } - if (removed && !Objects.equals(oldLayout, - mDataStore.getCurrentKeyboardLayout(key))) { - mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); - } - } finally { - mDataStore.saveIfNeeded(); - } - } + super.removeKeyboardLayoutForInputDevice_enforcePermission(); + mKeyboardLayoutManager.removeKeyboardLayoutForInputDevice(identifier, + keyboardLayoutDescriptor); } public void switchKeyboardLayout(int deviceId, int direction) { - mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, deviceId, direction).sendToTarget(); - } - - // Must be called on handler. - private void handleSwitchKeyboardLayout(int deviceId, int direction) { - final InputDevice device = getInputDevice(deviceId); - if (device != null) { - final boolean changed; - final String keyboardLayoutDescriptor; - - String key = getLayoutDescriptor(device.getIdentifier()); - synchronized (mDataStore) { - try { - changed = mDataStore.switchKeyboardLayout(key, direction); - keyboardLayoutDescriptor = mDataStore.getCurrentKeyboardLayout( - key); - } finally { - mDataStore.saveIfNeeded(); - } - } - - if (changed) { - if (mSwitchedKeyboardLayoutToast != null) { - mSwitchedKeyboardLayoutToast.cancel(); - mSwitchedKeyboardLayoutToast = null; - } - if (keyboardLayoutDescriptor != null) { - KeyboardLayout keyboardLayout = getKeyboardLayout(keyboardLayoutDescriptor); - if (keyboardLayout != null) { - mSwitchedKeyboardLayoutToast = Toast.makeText( - mContext, keyboardLayout.getLabel(), Toast.LENGTH_SHORT); - mSwitchedKeyboardLayoutToast.show(); - } - } - - reloadKeyboardLayouts(); - } - } + mKeyboardLayoutManager.switchKeyboardLayout(deviceId, direction); } public void setFocusedApplication(int displayId, InputApplicationHandle application) { @@ -2682,7 +2126,13 @@ public class InputManagerService extends IInputManager.Stub public String getInputDeviceBluetoothAddress(int deviceId) { super.getInputDeviceBluetoothAddress_enforcePermission(); - return mNative.getBluetoothAddress(deviceId); + final String address = mNative.getBluetoothAddress(deviceId); + if (address == null) return null; + if (!BluetoothAdapter.checkBluetoothAddress(address)) { + throw new IllegalStateException("The Bluetooth address of input device " + deviceId + + " should not be invalid: address=" + address); + } + return address; } @EnforcePermission(Manifest.permission.MONITOR_INPUT) @@ -2770,6 +2220,11 @@ public class InputManagerService extends IInputManager.Stub if (mOverriddenPointerDisplayId != Display.INVALID_DISPLAY) { pw.println("mOverriddenPointerDisplayId: " + mOverriddenPointerDisplayId); } + + pw.println("mAcknowledgedPointerDisplayId=" + mAcknowledgedPointerDisplayId); + pw.println("mRequestedPointerDisplayId=" + mRequestedPointerDisplayId); + pw.println("mPointerIconType=" + PointerIcon.typeToString(mPointerIconType)); + pw.println("mPointerIcon=" + mPointerIcon); } } private boolean checkCallingPermission(String permission, String func) { @@ -3252,28 +2707,7 @@ public class InputManagerService extends IInputManager.Stub if (!mSystemReady) { return null; } - - String keyboardLayoutDescriptor = getCurrentKeyboardLayoutForInputDevice(identifier); - if (keyboardLayoutDescriptor == null) { - return null; - } - - final String[] result = new String[2]; - visitKeyboardLayout(keyboardLayoutDescriptor, - (resources, keyboardLayoutResId, layout) -> { - try (InputStreamReader stream = new InputStreamReader( - resources.openRawResource(keyboardLayoutResId))) { - result[0] = layout.getDescriptor(); - result[1] = Streams.readFully(stream); - } catch (IOException | NotFoundException ignored) { - } - }); - if (result[0] == null) { - Slog.w(TAG, "Could not get keyboard layout with descriptor '" - + keyboardLayoutDescriptor + "'."); - return null; - } - return result; + return mKeyboardLayoutManager.getKeyboardLayoutOverlay(identifier); } // Native callback. @@ -3471,15 +2905,6 @@ public class InputManagerService extends IInputManager.Stub case MSG_DELIVER_INPUT_DEVICES_CHANGED: deliverInputDevicesChanged((InputDevice[])msg.obj); break; - case MSG_SWITCH_KEYBOARD_LAYOUT: - handleSwitchKeyboardLayout(msg.arg1, msg.arg2); - break; - case MSG_RELOAD_KEYBOARD_LAYOUTS: - reloadKeyboardLayouts(); - break; - case MSG_UPDATE_KEYBOARD_LAYOUTS: - updateKeyboardLayouts(); - break; case MSG_RELOAD_DEVICE_ALIASES: reloadDeviceAliases(); break; @@ -3548,39 +2973,6 @@ public class InputManagerService extends IInputManager.Stub } } - private static final class KeyboardLayoutDescriptor { - public String packageName; - public String receiverName; - public String keyboardLayoutName; - - public static String format(String packageName, - String receiverName, String keyboardName) { - return packageName + "/" + receiverName + "/" + keyboardName; - } - - public static KeyboardLayoutDescriptor parse(String descriptor) { - int pos = descriptor.indexOf('/'); - if (pos < 0 || pos + 1 == descriptor.length()) { - return null; - } - int pos2 = descriptor.indexOf('/', pos + 1); - if (pos2 < pos + 2 || pos2 + 1 == descriptor.length()) { - return null; - } - - KeyboardLayoutDescriptor result = new KeyboardLayoutDescriptor(); - result.packageName = descriptor.substring(0, pos); - result.receiverName = descriptor.substring(pos + 1, pos2); - result.keyboardLayoutName = descriptor.substring(pos2 + 1); - return result; - } - } - - private interface KeyboardLayoutVisitor { - void visitKeyboardLayout(Resources resources, - int keyboardLayoutResId, KeyboardLayout layout); - } - private final class InputDevicesChangedListenerRecord implements DeathRecipient { private final int mPid; private final IInputDevicesChangedListener mListener; diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java new file mode 100644 index 000000000000..fac001e7828f --- /dev/null +++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java @@ -0,0 +1,736 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.input; + +import android.annotation.NonNull; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.hardware.input.InputDeviceIdentifier; +import android.hardware.input.InputManager; +import android.hardware.input.KeyboardLayout; +import android.os.Bundle; +import android.os.Handler; +import android.os.LocaleList; +import android.os.Looper; +import android.os.Message; +import android.os.UserHandle; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; +import android.util.Slog; +import android.view.InputDevice; +import android.widget.Toast; + +import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; +import com.android.internal.messages.nano.SystemMessageProto; +import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.util.XmlUtils; + +import libcore.io.Streams; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.stream.Stream; + +/** + * A component of {@link InputManagerService} responsible for managing Physical Keyboard layouts. + * + * @hide + */ +final class KeyboardLayoutManager implements InputManager.InputDeviceListener { + + private static final String TAG = "KeyboardLayoutManager"; + + // To enable these logs, run: 'adb shell setprop log.tag.KeyboardLayoutManager DEBUG' + // (requires restart) + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 1; + private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 2; + private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 3; + + private final Context mContext; + private final NativeInputManagerService mNative; + // The PersistentDataStore should be locked before use. + @GuardedBy("mDataStore") + private final PersistentDataStore mDataStore; + private final Handler mHandler; + private final List<InputDevice> mKeyboardsWithMissingLayouts = new ArrayList<>(); + private boolean mKeyboardLayoutNotificationShown = false; + private Toast mSwitchedKeyboardLayoutToast; + + KeyboardLayoutManager(Context context, NativeInputManagerService nativeService, + PersistentDataStore dataStore, Looper looper) { + mContext = context; + mNative = nativeService; + mDataStore = dataStore; + mHandler = new Handler(looper, this::handleMessage, true /* async */); + } + + public void systemRunning() { + // Listen to new Package installations to fetch new Keyboard layouts + IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); + filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addAction(Intent.ACTION_PACKAGE_CHANGED); + filter.addAction(Intent.ACTION_PACKAGE_REPLACED); + filter.addDataScheme("package"); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + updateKeyboardLayouts(); + } + }, filter, null, mHandler); + + mHandler.sendEmptyMessage(MSG_UPDATE_KEYBOARD_LAYOUTS); + + // Listen to new InputDevice changes + InputManager inputManager = Objects.requireNonNull( + mContext.getSystemService(InputManager.class)); + inputManager.registerInputDeviceListener(this, mHandler); + // Circle through all the already added input devices + for (int deviceId : inputManager.getInputDeviceIds()) { + onInputDeviceAdded(deviceId); + } + } + + @Override + public void onInputDeviceAdded(int deviceId) { + onInputDeviceChanged(deviceId); + } + + @Override + public void onInputDeviceRemoved(int deviceId) { + mKeyboardsWithMissingLayouts.removeIf(device -> device.getId() == deviceId); + maybeUpdateNotification(); + } + + @Override + public void onInputDeviceChanged(int deviceId) { + final InputDevice inputDevice = getInputDevice(deviceId); + if (inputDevice == null) { + return; + } + synchronized (mDataStore) { + String layout = getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier()); + if (layout == null) { + layout = getDefaultKeyboardLayout(inputDevice); + if (layout != null) { + setCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier(), layout); + } else { + mKeyboardsWithMissingLayouts.add(inputDevice); + } + } + maybeUpdateNotification(); + } + } + + private String getDefaultKeyboardLayout(final InputDevice inputDevice) { + final Locale systemLocale = mContext.getResources().getConfiguration().locale; + // If our locale doesn't have a language for some reason, then we don't really have a + // reasonable default. + if (TextUtils.isEmpty(systemLocale.getLanguage())) { + return null; + } + final List<KeyboardLayout> layouts = new ArrayList<>(); + visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> { + // Only select a default when we know the layout is appropriate. For now, this + // means it's a custom layout for a specific keyboard. + if (layout.getVendorId() != inputDevice.getVendorId() + || layout.getProductId() != inputDevice.getProductId()) { + return; + } + final LocaleList locales = layout.getLocales(); + for (int localeIndex = 0; localeIndex < locales.size(); ++localeIndex) { + final Locale locale = locales.get(localeIndex); + if (locale != null && isCompatibleLocale(systemLocale, locale)) { + layouts.add(layout); + break; + } + } + }); + + if (layouts.isEmpty()) { + return null; + } + + // First sort so that ones with higher priority are listed at the top + Collections.sort(layouts); + // Next we want to try to find an exact match of language, country and variant. + for (KeyboardLayout layout : layouts) { + final LocaleList locales = layout.getLocales(); + for (int localeIndex = 0; localeIndex < locales.size(); ++localeIndex) { + final Locale locale = locales.get(localeIndex); + if (locale != null && locale.getCountry().equals(systemLocale.getCountry()) + && locale.getVariant().equals(systemLocale.getVariant())) { + return layout.getDescriptor(); + } + } + } + // Then try an exact match of language and country + for (KeyboardLayout layout : layouts) { + final LocaleList locales = layout.getLocales(); + for (int localeIndex = 0; localeIndex < locales.size(); ++localeIndex) { + final Locale locale = locales.get(localeIndex); + if (locale != null && locale.getCountry().equals(systemLocale.getCountry())) { + return layout.getDescriptor(); + } + } + } + + // Give up and just use the highest priority layout with matching language + return layouts.get(0).getDescriptor(); + } + + private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) { + // Different languages are never compatible + if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) { + return false; + } + // If both the system and the keyboard layout have a country specifier, they must be equal. + return TextUtils.isEmpty(systemLocale.getCountry()) + || TextUtils.isEmpty(keyboardLocale.getCountry()) + || systemLocale.getCountry().equals(keyboardLocale.getCountry()); + } + + private void updateKeyboardLayouts() { + // Scan all input devices state for keyboard layouts that have been uninstalled. + final HashSet<String> availableKeyboardLayouts = new HashSet<String>(); + visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> + availableKeyboardLayouts.add(layout.getDescriptor())); + synchronized (mDataStore) { + try { + mDataStore.removeUninstalledKeyboardLayouts(availableKeyboardLayouts); + } finally { + mDataStore.saveIfNeeded(); + } + } + + // Reload keyboard layouts. + reloadKeyboardLayouts(); + } + + public KeyboardLayout[] getKeyboardLayouts() { + final ArrayList<KeyboardLayout> list = new ArrayList<>(); + visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> list.add(layout)); + return list.toArray(new KeyboardLayout[0]); + } + + public KeyboardLayout[] getKeyboardLayoutsForInputDevice( + final InputDeviceIdentifier identifier) { + final String[] enabledLayoutDescriptors = + getEnabledKeyboardLayoutsForInputDevice(identifier); + final ArrayList<KeyboardLayout> enabledLayouts = + new ArrayList<>(enabledLayoutDescriptors.length); + final ArrayList<KeyboardLayout> potentialLayouts = new ArrayList<>(); + visitAllKeyboardLayouts(new KeyboardLayoutVisitor() { + boolean mHasSeenDeviceSpecificLayout; + + @Override + public void visitKeyboardLayout(Resources resources, + int keyboardLayoutResId, KeyboardLayout layout) { + // First check if it's enabled. If the keyboard layout is enabled then we always + // want to return it as a possible layout for the device. + for (String s : enabledLayoutDescriptors) { + if (s != null && s.equals(layout.getDescriptor())) { + enabledLayouts.add(layout); + return; + } + } + // Next find any potential layouts that aren't yet enabled for the device. For + // devices that have special layouts we assume there's a reason that the generic + // layouts don't work for them so we don't want to return them since it's likely + // to result in a poor user experience. + if (layout.getVendorId() == identifier.getVendorId() + && layout.getProductId() == identifier.getProductId()) { + if (!mHasSeenDeviceSpecificLayout) { + mHasSeenDeviceSpecificLayout = true; + potentialLayouts.clear(); + } + potentialLayouts.add(layout); + } else if (layout.getVendorId() == -1 && layout.getProductId() == -1 + && !mHasSeenDeviceSpecificLayout) { + potentialLayouts.add(layout); + } + } + }); + return Stream.concat(enabledLayouts.stream(), potentialLayouts.stream()).toArray( + KeyboardLayout[]::new); + } + + public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { + Objects.requireNonNull(keyboardLayoutDescriptor, + "keyboardLayoutDescriptor must not be null"); + + final KeyboardLayout[] result = new KeyboardLayout[1]; + visitKeyboardLayout(keyboardLayoutDescriptor, + (resources, keyboardLayoutResId, layout) -> result[0] = layout); + if (result[0] == null) { + Slog.w(TAG, "Could not get keyboard layout with descriptor '" + + keyboardLayoutDescriptor + "'."); + } + return result[0]; + } + + private void visitAllKeyboardLayouts(KeyboardLayoutVisitor visitor) { + final PackageManager pm = mContext.getPackageManager(); + Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_LAYOUTS); + for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent, + PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE)) { + final ActivityInfo activityInfo = resolveInfo.activityInfo; + final int priority = resolveInfo.priority; + visitKeyboardLayoutsInPackage(pm, activityInfo, null, priority, visitor); + } + } + + private void visitKeyboardLayout(String keyboardLayoutDescriptor, + KeyboardLayoutVisitor visitor) { + KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(keyboardLayoutDescriptor); + if (d != null) { + final PackageManager pm = mContext.getPackageManager(); + try { + ActivityInfo receiver = pm.getReceiverInfo( + new ComponentName(d.packageName, d.receiverName), + PackageManager.GET_META_DATA + | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + visitKeyboardLayoutsInPackage(pm, receiver, d.keyboardLayoutName, 0, visitor); + } catch (PackageManager.NameNotFoundException ignored) { + } + } + } + + private void visitKeyboardLayoutsInPackage(PackageManager pm, ActivityInfo receiver, + String keyboardName, int requestedPriority, KeyboardLayoutVisitor visitor) { + Bundle metaData = receiver.metaData; + if (metaData == null) { + return; + } + + int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_LAYOUTS); + if (configResId == 0) { + Slog.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_LAYOUTS + + "' on receiver " + receiver.packageName + "/" + receiver.name); + return; + } + + CharSequence receiverLabel = receiver.loadLabel(pm); + String collection = receiverLabel != null ? receiverLabel.toString() : ""; + int priority; + if ((receiver.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + priority = requestedPriority; + } else { + priority = 0; + } + + try { + Resources resources = pm.getResourcesForApplication(receiver.applicationInfo); + try (XmlResourceParser parser = resources.getXml(configResId)) { + XmlUtils.beginDocument(parser, "keyboard-layouts"); + + while (true) { + XmlUtils.nextElement(parser); + String element = parser.getName(); + if (element == null) { + break; + } + if (element.equals("keyboard-layout")) { + TypedArray a = resources.obtainAttributes( + parser, R.styleable.KeyboardLayout); + try { + String name = a.getString( + R.styleable.KeyboardLayout_name); + String label = a.getString( + R.styleable.KeyboardLayout_label); + int keyboardLayoutResId = a.getResourceId( + R.styleable.KeyboardLayout_keyboardLayout, + 0); + String languageTags = a.getString( + R.styleable.KeyboardLayout_locale); + LocaleList locales = getLocalesFromLanguageTags(languageTags); + int vid = a.getInt( + R.styleable.KeyboardLayout_vendorId, -1); + int pid = a.getInt( + R.styleable.KeyboardLayout_productId, -1); + + if (name == null || label == null || keyboardLayoutResId == 0) { + Slog.w(TAG, "Missing required 'name', 'label' or 'keyboardLayout' " + + "attributes in keyboard layout " + + "resource from receiver " + + receiver.packageName + "/" + receiver.name); + } else { + String descriptor = KeyboardLayoutDescriptor.format( + receiver.packageName, receiver.name, name); + if (keyboardName == null || name.equals(keyboardName)) { + KeyboardLayout layout = new KeyboardLayout( + descriptor, label, collection, priority, + locales, vid, pid); + visitor.visitKeyboardLayout( + resources, keyboardLayoutResId, layout); + } + } + } finally { + a.recycle(); + } + } else { + Slog.w(TAG, "Skipping unrecognized element '" + element + + "' in keyboard layout resource from receiver " + + receiver.packageName + "/" + receiver.name); + } + } + } + } catch (Exception ex) { + Slog.w(TAG, "Could not parse keyboard layout resource from receiver " + + receiver.packageName + "/" + receiver.name, ex); + } + } + + @NonNull + private static LocaleList getLocalesFromLanguageTags(String languageTags) { + if (TextUtils.isEmpty(languageTags)) { + return LocaleList.getEmptyLocaleList(); + } + return LocaleList.forLanguageTags(languageTags.replace('|', ',')); + } + + /** + * Builds a layout descriptor for the vendor/product. This returns the + * descriptor for ids that aren't useful (such as the default 0, 0). + */ + private String getLayoutDescriptor(InputDeviceIdentifier identifier) { + Objects.requireNonNull(identifier, "identifier must not be null"); + Objects.requireNonNull(identifier.getDescriptor(), "descriptor must not be null"); + + if (identifier.getVendorId() == 0 && identifier.getProductId() == 0) { + return identifier.getDescriptor(); + } + return "vendor:" + identifier.getVendorId() + ",product:" + identifier.getProductId(); + } + + public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) { + String key = getLayoutDescriptor(identifier); + synchronized (mDataStore) { + String layout; + // try loading it using the layout descriptor if we have it + layout = mDataStore.getCurrentKeyboardLayout(key); + if (layout == null && !key.equals(identifier.getDescriptor())) { + // if it doesn't exist fall back to the device descriptor + layout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); + } + if (DEBUG) { + Slog.d(TAG, "getCurrentKeyboardLayoutForInputDevice() " + + identifier.toString() + ": " + layout); + } + return layout; + } + } + + public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, + String keyboardLayoutDescriptor) { + Objects.requireNonNull(keyboardLayoutDescriptor, + "keyboardLayoutDescriptor must not be null"); + + String key = getLayoutDescriptor(identifier); + synchronized (mDataStore) { + try { + if (mDataStore.setCurrentKeyboardLayout(key, keyboardLayoutDescriptor)) { + if (DEBUG) { + Slog.d(TAG, "setCurrentKeyboardLayoutForInputDevice() " + identifier + + " key: " + key + + " keyboardLayoutDescriptor: " + keyboardLayoutDescriptor); + } + mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); + } + } finally { + mDataStore.saveIfNeeded(); + } + } + } + + public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) { + String key = getLayoutDescriptor(identifier); + synchronized (mDataStore) { + String[] layouts = mDataStore.getKeyboardLayouts(key); + if ((layouts == null || layouts.length == 0) + && !key.equals(identifier.getDescriptor())) { + layouts = mDataStore.getKeyboardLayouts(identifier.getDescriptor()); + } + return layouts; + } + } + + public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, + String keyboardLayoutDescriptor) { + Objects.requireNonNull(keyboardLayoutDescriptor, + "keyboardLayoutDescriptor must not be null"); + + String key = getLayoutDescriptor(identifier); + synchronized (mDataStore) { + try { + String oldLayout = mDataStore.getCurrentKeyboardLayout(key); + if (oldLayout == null && !key.equals(identifier.getDescriptor())) { + oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); + } + if (mDataStore.addKeyboardLayout(key, keyboardLayoutDescriptor) + && !Objects.equals(oldLayout, + mDataStore.getCurrentKeyboardLayout(key))) { + mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); + } + } finally { + mDataStore.saveIfNeeded(); + } + } + } + + public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, + String keyboardLayoutDescriptor) { + Objects.requireNonNull(keyboardLayoutDescriptor, + "keyboardLayoutDescriptor must not be null"); + + String key = getLayoutDescriptor(identifier); + synchronized (mDataStore) { + try { + String oldLayout = mDataStore.getCurrentKeyboardLayout(key); + if (oldLayout == null && !key.equals(identifier.getDescriptor())) { + oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); + } + boolean removed = mDataStore.removeKeyboardLayout(key, keyboardLayoutDescriptor); + if (!key.equals(identifier.getDescriptor())) { + // We need to remove from both places to ensure it is gone + removed |= mDataStore.removeKeyboardLayout(identifier.getDescriptor(), + keyboardLayoutDescriptor); + } + if (removed && !Objects.equals(oldLayout, + mDataStore.getCurrentKeyboardLayout(key))) { + mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); + } + } finally { + mDataStore.saveIfNeeded(); + } + } + } + + public void switchKeyboardLayout(int deviceId, int direction) { + mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, deviceId, direction).sendToTarget(); + } + + // Must be called on handler. + private void handleSwitchKeyboardLayout(int deviceId, int direction) { + final InputDevice device = getInputDevice(deviceId); + if (device != null) { + final boolean changed; + final String keyboardLayoutDescriptor; + + String key = getLayoutDescriptor(device.getIdentifier()); + synchronized (mDataStore) { + try { + changed = mDataStore.switchKeyboardLayout(key, direction); + keyboardLayoutDescriptor = mDataStore.getCurrentKeyboardLayout( + key); + } finally { + mDataStore.saveIfNeeded(); + } + } + + if (changed) { + if (mSwitchedKeyboardLayoutToast != null) { + mSwitchedKeyboardLayoutToast.cancel(); + mSwitchedKeyboardLayoutToast = null; + } + if (keyboardLayoutDescriptor != null) { + KeyboardLayout keyboardLayout = getKeyboardLayout(keyboardLayoutDescriptor); + if (keyboardLayout != null) { + mSwitchedKeyboardLayoutToast = Toast.makeText( + mContext, keyboardLayout.getLabel(), Toast.LENGTH_SHORT); + mSwitchedKeyboardLayoutToast.show(); + } + } + + reloadKeyboardLayouts(); + } + } + } + + public String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier) { + String keyboardLayoutDescriptor = getCurrentKeyboardLayoutForInputDevice(identifier); + if (keyboardLayoutDescriptor == null) { + return null; + } + + final String[] result = new String[2]; + visitKeyboardLayout(keyboardLayoutDescriptor, + (resources, keyboardLayoutResId, layout) -> { + try (InputStreamReader stream = new InputStreamReader( + resources.openRawResource(keyboardLayoutResId))) { + result[0] = layout.getDescriptor(); + result[1] = Streams.readFully(stream); + } catch (IOException | Resources.NotFoundException ignored) { + } + }); + if (result[0] == null) { + Slog.w(TAG, "Could not get keyboard layout with descriptor '" + + keyboardLayoutDescriptor + "'."); + return null; + } + return result; + } + + private void reloadKeyboardLayouts() { + if (DEBUG) { + Slog.d(TAG, "Reloading keyboard layouts."); + } + mNative.reloadKeyboardLayouts(); + } + + private void maybeUpdateNotification() { + NotificationManager notificationManager = mContext.getSystemService( + NotificationManager.class); + if (notificationManager == null) { + return; + } + if (!mKeyboardsWithMissingLayouts.isEmpty()) { + if (mKeyboardsWithMissingLayouts.size() > 1) { + // We have more than one keyboard missing a layout, so drop the + // user at the generic input methods page, so they can pick which + // one to set. + showMissingKeyboardLayoutNotification(notificationManager, null); + } else { + showMissingKeyboardLayoutNotification(notificationManager, + mKeyboardsWithMissingLayouts.get(0)); + } + } else if (mKeyboardLayoutNotificationShown) { + hideMissingKeyboardLayoutNotification(notificationManager); + } + } + + // Must be called on handler. + private void showMissingKeyboardLayoutNotification(NotificationManager notificationManager, + InputDevice device) { + if (!mKeyboardLayoutNotificationShown) { + final Intent intent = new Intent(Settings.ACTION_HARD_KEYBOARD_SETTINGS); + if (device != null) { + intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, device.getIdentifier()); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0, + intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); + + Resources r = mContext.getResources(); + Notification notification = + new Notification.Builder(mContext, SystemNotificationChannels.PHYSICAL_KEYBOARD) + .setContentTitle(r.getString( + R.string.select_keyboard_layout_notification_title)) + .setContentText(r.getString( + R.string.select_keyboard_layout_notification_message)) + .setContentIntent(keyboardLayoutIntent) + .setSmallIcon(R.drawable.ic_settings_language) + .setColor(mContext.getColor( + com.android.internal.R.color.system_notification_accent_color)) + .build(); + notificationManager.notifyAsUser(null, + SystemMessageProto.SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT, + notification, UserHandle.ALL); + mKeyboardLayoutNotificationShown = true; + } + } + + // Must be called on handler. + private void hideMissingKeyboardLayoutNotification(NotificationManager notificationManager) { + if (mKeyboardLayoutNotificationShown) { + mKeyboardLayoutNotificationShown = false; + notificationManager.cancelAsUser(null, + SystemMessageProto.SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT, + UserHandle.ALL); + } + } + + private boolean handleMessage(Message msg) { + switch (msg.what) { + case MSG_SWITCH_KEYBOARD_LAYOUT: + handleSwitchKeyboardLayout(msg.arg1, msg.arg2); + return true; + case MSG_RELOAD_KEYBOARD_LAYOUTS: + reloadKeyboardLayouts(); + return true; + case MSG_UPDATE_KEYBOARD_LAYOUTS: + updateKeyboardLayouts(); + return true; + default: + return false; + } + } + + private InputDevice getInputDevice(int deviceId) { + InputManager inputManager = mContext.getSystemService(InputManager.class); + return inputManager != null ? inputManager.getInputDevice(deviceId) : null; + } + + private static final class KeyboardLayoutDescriptor { + public String packageName; + public String receiverName; + public String keyboardLayoutName; + + public static String format(String packageName, + String receiverName, String keyboardName) { + return packageName + "/" + receiverName + "/" + keyboardName; + } + + public static KeyboardLayoutDescriptor parse(String descriptor) { + int pos = descriptor.indexOf('/'); + if (pos < 0 || pos + 1 == descriptor.length()) { + return null; + } + int pos2 = descriptor.indexOf('/', pos + 1); + if (pos2 < pos + 2 || pos2 + 1 == descriptor.length()) { + return null; + } + + KeyboardLayoutDescriptor result = new KeyboardLayoutDescriptor(); + result.packageName = descriptor.substring(0, pos); + result.receiverName = descriptor.substring(pos + 1, pos2); + result.keyboardLayoutName = descriptor.substring(pos2 + 1); + return result; + } + } + + private interface KeyboardLayoutVisitor { + void visitKeyboardLayout(Resources resources, + int keyboardLayoutResId, KeyboardLayout layout); + } +} diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index a6b7fe2a29b6..d6846bed2a14 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -41,6 +41,7 @@ import android.media.MediaRoute2ProviderInfo; import android.media.MediaRoute2ProviderService; import android.media.MediaRouter2Manager; import android.media.RouteDiscoveryPreference; +import android.media.RouteListingPreference; import android.media.RoutingSessionInfo; import android.os.Binder; import android.os.Bundle; @@ -257,6 +258,24 @@ class MediaRouter2ServiceImpl { } } + public void setRouteListingPreference( + @NonNull IMediaRouter2 router, + @Nullable RouteListingPreference routeListingPreference) { + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + RouterRecord routerRecord = mAllRouterRecords.get(router.asBinder()); + if (routerRecord == null) { + Slog.w(TAG, "Ignoring updating route listing of null routerRecord."); + return; + } + setRouteListingPreferenceLocked(routerRecord, routeListingPreference); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + public void setRouteVolumeWithRouter2(@NonNull IMediaRouter2 router, @NonNull MediaRoute2Info route, int volume) { Objects.requireNonNull(router, "router must not be null"); @@ -648,9 +667,11 @@ class MediaRouter2ServiceImpl { "userId: %d", newActiveUserId)); mCurrentActiveUserId = newActiveUserId; - for (int i = 0; i < mUserRecords.size(); i++) { - int userId = mUserRecords.keyAt(i); - UserRecord userRecord = mUserRecords.valueAt(i); + // disposeUserIfNeededLocked might modify the collection, hence clone + final var userRecords = mUserRecords.clone(); + for (int i = 0; i < userRecords.size(); i++) { + int userId = userRecords.keyAt(i); + UserRecord userRecord = userRecords.valueAt(i); if (isUserActiveLocked(userId)) { // userId corresponds to the active user, or one of its profiles. We // ensure the associated structures are initialized. @@ -771,6 +792,31 @@ class MediaRouter2ServiceImpl { routerRecord.mUserRecord.mHandler)); } + @GuardedBy("mLock") + private void setRouteListingPreferenceLocked( + RouterRecord routerRecord, @Nullable RouteListingPreference routeListingPreference) { + routerRecord.mRouteListingPreference = routeListingPreference; + String routeListingAsString = + routeListingPreference != null + ? routeListingPreference.getItems().stream() + .map(RouteListingPreference.Item::getRouteId) + .collect(Collectors.joining(",")) + : null; + mEventLogger.enqueue( + EventLogger.StringEvent.from( + "setRouteListingPreference", + "router id: %d, route listing preference: [%s]", + routerRecord.mRouterId, + routeListingAsString)); + + routerRecord.mUserRecord.mHandler.sendMessage( + obtainMessage( + UserHandler::notifyRouteListingPreferenceChangeToManagers, + routerRecord.mUserRecord.mHandler, + routerRecord.mPackageName, + routeListingPreference)); + } + private void setRouteVolumeWithRouter2Locked(@NonNull IMediaRouter2 router, @NonNull MediaRoute2Info route, int volume) { final IBinder binder = router.asBinder(); @@ -1021,6 +1067,15 @@ class MediaRouter2ServiceImpl { // RouteCallback#onRoutesAdded() for system MR2 will never be called with initial routes // due to the lack of features. for (RouterRecord routerRecord : userRecord.mRouterRecords) { + // Send route listing preferences before discovery preferences and routes to avoid an + // inconsistent state where there are routes to show, but the manager thinks + // the app has not expressed a preference for listing. + userRecord.mHandler.sendMessage( + obtainMessage( + UserHandler::notifyRouteListingPreferenceChangeToManagers, + routerRecord.mUserRecord.mHandler, + routerRecord.mPackageName, + routerRecord.mRouteListingPreference)); // TODO: UserRecord <-> routerRecord, why do they reference each other? // How about removing mUserRecord from routerRecord? routerRecord.mUserRecord.mHandler.sendMessage( @@ -1400,6 +1455,7 @@ class MediaRouter2ServiceImpl { public final int mRouterId; public RouteDiscoveryPreference mDiscoveryPreference; + @Nullable public RouteListingPreference mRouteListingPreference; RouterRecord(UserRecord userRecord, IMediaRouter2 router, int uid, int pid, String packageName, boolean hasConfigureWifiDisplayPermission, @@ -1688,6 +1744,9 @@ class MediaRouter2ServiceImpl { indexOfRouteProviderInfoByUniqueId(provider.getUniqueId(), mLastProviderInfos); MediaRoute2ProviderInfo oldInfo = providerInfoIndex == -1 ? null : mLastProviderInfos.get(providerInfoIndex); + MediaRouter2ServiceImpl mediaRouter2Service = mServiceRef.get(); + EventLogger eventLogger = + mediaRouter2Service != null ? mediaRouter2Service.mEventLogger : null; if (oldInfo == newInfo) { // Nothing to do. return; @@ -1713,6 +1772,7 @@ class MediaRouter2ServiceImpl { } // Add new routes to the maps. + ArrayList<MediaRoute2Info> addedRoutes = new ArrayList<>(); boolean hasAddedOrModifiedRoutes = false; for (MediaRoute2Info newRouteInfo : newRoutes) { if (!newRouteInfo.isValid()) { @@ -1727,11 +1787,14 @@ class MediaRouter2ServiceImpl { MediaRoute2Info oldRouteInfo = mLastNotifiedRoutesToPrivilegedRouters.put( newRouteInfo.getId(), newRouteInfo); - hasAddedOrModifiedRoutes |= - oldRouteInfo == null || !oldRouteInfo.equals(newRouteInfo); + hasAddedOrModifiedRoutes |= !newRouteInfo.equals(oldRouteInfo); + if (oldRouteInfo == null) { + addedRoutes.add(newRouteInfo); + } } // Remove stale routes from the maps. + ArrayList<MediaRoute2Info> removedRoutes = new ArrayList<>(); Collection<MediaRoute2Info> oldRoutes = oldInfo == null ? Collections.emptyList() : oldInfo.getRoutes(); boolean hasRemovedRoutes = false; @@ -1741,6 +1804,26 @@ class MediaRouter2ServiceImpl { hasRemovedRoutes = true; mLastNotifiedRoutesToPrivilegedRouters.remove(oldRouteId); mLastNotifiedRoutesToNonPrivilegedRouters.remove(oldRouteId); + removedRoutes.add(oldRoute); + } + } + + if (eventLogger != null) { + if (!addedRoutes.isEmpty()) { + // If routes were added, newInfo cannot be null. + eventLogger.enqueue( + toLoggingEvent( + /* source= */ "addProviderRoutes", + newInfo.getUniqueId(), + addedRoutes)); + } + if (!removedRoutes.isEmpty()) { + // If routes were removed, oldInfo cannot be null. + eventLogger.enqueue( + toLoggingEvent( + /* source= */ "removeProviderRoutes", + oldInfo.getUniqueId(), + removedRoutes)); } } @@ -1751,6 +1834,16 @@ class MediaRouter2ServiceImpl { mSystemProvider.getDefaultRoute()); } + private static EventLogger.Event toLoggingEvent( + String source, String providerId, ArrayList<MediaRoute2Info> routes) { + String routesString = + routes.stream() + .map(it -> String.format("%s | %s", it.getOriginalId(), it.getName())) + .collect(Collectors.joining(/* delimiter= */ ", ")); + return EventLogger.StringEvent.from( + source, "provider: %s, routes: [%s]", providerId, routesString); + } + /** * Dispatches the latest route updates in {@link #mLastNotifiedRoutesToPrivilegedRouters} * and {@link #mLastNotifiedRoutesToNonPrivilegedRouters} to registered {@link @@ -2427,6 +2520,34 @@ class MediaRouter2ServiceImpl { } } + private void notifyRouteListingPreferenceChangeToManagers( + String routerPackageName, @Nullable RouteListingPreference routeListingPreference) { + MediaRouter2ServiceImpl service = mServiceRef.get(); + if (service == null) { + return; + } + List<IMediaRouter2Manager> managers = new ArrayList<>(); + synchronized (service.mLock) { + for (ManagerRecord managerRecord : mUserRecord.mManagerRecords) { + managers.add(managerRecord.mManager); + } + } + for (IMediaRouter2Manager manager : managers) { + try { + manager.notifyRouteListingPreferenceChange( + routerPackageName, routeListingPreference); + } catch (RemoteException ex) { + Slog.w( + TAG, + "Failed to notify preferred features changed." + + " Manager probably died.", + ex); + } + } + // TODO(b/238178508): In order to support privileged media router instances, we also + // need to update routers other than the one making the update. + } + private void notifyRequestFailedToManager(@NonNull IMediaRouter2Manager manager, int requestId, int reason) { try { @@ -2506,7 +2627,6 @@ class MediaRouter2ServiceImpl { } return null; } - } static final class SessionCreationRequest { public final RouterRecord mRouterRecord; diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index c0340b1eaa13..beab5ea5bcb0 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -17,6 +17,7 @@ package com.android.server.media; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.UserSwitchObserver; @@ -43,6 +44,7 @@ import android.media.MediaRouterClientState; import android.media.RemoteDisplayState; import android.media.RemoteDisplayState.RemoteDisplayInfo; import android.media.RouteDiscoveryPreference; +import android.media.RouteListingPreference; import android.media.RoutingSessionInfo; import android.os.Binder; import android.os.Bundle; @@ -420,6 +422,14 @@ public final class MediaRouterService extends IMediaRouterService.Stub // Binder call @Override + public void setRouteListingPreference( + @NonNull IMediaRouter2 router, + @Nullable RouteListingPreference routeListingPreference) { + mService2.setRouteListingPreference(router, routeListingPreference); + } + + // Binder call + @Override public void setRouteVolumeWithRouter2(IMediaRouter2 router, MediaRoute2Info route, int volume) { mService2.setRouteVolumeWithRouter2(router, route, volume); @@ -628,9 +638,11 @@ public final class MediaRouterService extends IMediaRouterService.Stub synchronized (mLock) { if (mCurrentActiveUserId != newActiveUserId) { mCurrentActiveUserId = newActiveUserId; - for (int i = 0; i < mUserRecords.size(); i++) { - int userId = mUserRecords.keyAt(i); - UserRecord userRecord = mUserRecords.valueAt(i); + // disposeUserIfNeededLocked might modify the collection, hence clone + final var userRecords = mUserRecords.clone(); + for (int i = 0; i < userRecords.size(); i++) { + int userId = userRecords.keyAt(i); + UserRecord userRecord = userRecords.valueAt(i); if (isUserActiveLocked(userId)) { // userId corresponds to the active user, or one of its profiles. We // ensure the associated structures are initialized. diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index 337d5e51ddfb..f2a39b8960cf 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -24,6 +24,8 @@ import android.os.UserHandle; import android.util.Log; import android.util.SparseArray; +import com.android.server.utils.EventLogger; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -38,6 +40,8 @@ class MediaSessionStack { private static final boolean DEBUG = MediaSessionService.DEBUG; private static final String TAG = "MediaSessionStack"; + private static final int DUMP_EVENTS_MAX_COUNT = 70; + /** * Listen the change in the media button session. */ @@ -57,6 +61,8 @@ class MediaSessionStack { private final AudioPlayerStateMonitor mAudioPlayerStateMonitor; private final OnMediaButtonSessionChangedListener mOnMediaButtonSessionChangedListener; + private final EventLogger mEventLogger = new EventLogger(DUMP_EVENTS_MAX_COUNT, TAG); + /** * The media button session which receives media key events. * It could be null if the previous media button session is released. @@ -80,6 +86,11 @@ class MediaSessionStack { * @param record The record to add. */ public void addSession(MediaSessionRecordImpl record) { + mEventLogger.enqueue(EventLogger.StringEvent.from( + "addSession() (to bottom of stack)", + "record: %s", + record + )); mSessions.add(record); clearCache(record.getUserId()); @@ -95,6 +106,11 @@ class MediaSessionStack { * @param record The record to remove. */ public void removeSession(MediaSessionRecordImpl record) { + mEventLogger.enqueue(EventLogger.StringEvent.from( + "removeSession()", + "record: %s", + record + )); mSessions.remove(record); if (mMediaButtonSession == record) { // When the media button session is removed, nullify the media button session and do not @@ -140,6 +156,11 @@ class MediaSessionStack { public void onPlaybackStateChanged( MediaSessionRecordImpl record, boolean shouldUpdatePriority) { if (shouldUpdatePriority) { + mEventLogger.enqueue(EventLogger.StringEvent.from( + "onPlaybackStateChanged() - Pushing session to top", + "record: %s", + record + )); mSessions.remove(record); mSessions.add(0, record); clearCache(record.getUserId()); @@ -344,6 +365,8 @@ class MediaSessionStack { for (MediaSessionRecordImpl record : mSessions) { record.dump(pw, indent); } + pw.println(prefix + "Session stack events:"); + mEventLogger.dump(pw, indent); } /** diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index d6b9bd5d3114..90135ad7684b 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3797,13 +3797,13 @@ public class NotificationManagerService extends SystemService { } private void createNotificationChannelsImpl(String pkg, int uid, - ParceledListSlice channelsList, boolean fromTargetApp) { - createNotificationChannelsImpl(pkg, uid, channelsList, fromTargetApp, + ParceledListSlice channelsList) { + createNotificationChannelsImpl(pkg, uid, channelsList, ActivityTaskManager.INVALID_TASK_ID); } private void createNotificationChannelsImpl(String pkg, int uid, - ParceledListSlice channelsList, boolean fromTargetApp, int startingTaskId) { + ParceledListSlice channelsList, int startingTaskId) { List<NotificationChannel> channels = channelsList.getList(); final int channelsSize = channels.size(); ParceledListSlice<NotificationChannel> oldChannels = @@ -3815,7 +3815,7 @@ public class NotificationManagerService extends SystemService { final NotificationChannel channel = channels.get(i); Objects.requireNonNull(channel, "channel in list is null"); needsPolicyFileChange = mPreferencesHelper.createNotificationChannel(pkg, uid, - channel, fromTargetApp, + channel, true /* fromTargetApp */, mConditionProviders.isPackageOrComponentAllowed( pkg, UserHandle.getUserId(uid))); if (needsPolicyFileChange) { @@ -3851,7 +3851,6 @@ public class NotificationManagerService extends SystemService { @Override public void createNotificationChannels(String pkg, ParceledListSlice channelsList) { checkCallerIsSystemOrSameApp(pkg); - boolean fromTargetApp = !isCallerSystemOrPhone(); // if not system, it's from the app int taskId = ActivityTaskManager.INVALID_TASK_ID; try { int uid = mPackageManager.getPackageUid(pkg, 0, @@ -3860,15 +3859,14 @@ public class NotificationManagerService extends SystemService { } catch (RemoteException e) { // Do nothing } - createNotificationChannelsImpl(pkg, Binder.getCallingUid(), channelsList, fromTargetApp, - taskId); + createNotificationChannelsImpl(pkg, Binder.getCallingUid(), channelsList, taskId); } @Override public void createNotificationChannelsForPackage(String pkg, int uid, ParceledListSlice channelsList) { enforceSystemOrSystemUI("only system can call this"); - createNotificationChannelsImpl(pkg, uid, channelsList, false /* fromTargetApp */); + createNotificationChannelsImpl(pkg, uid, channelsList); } @Override @@ -3883,8 +3881,7 @@ public class NotificationManagerService extends SystemService { CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId)); conversationChannel.setConversationId(parentId, conversationId); createNotificationChannelsImpl( - pkg, uid, new ParceledListSlice(Arrays.asList(conversationChannel)), - false /* fromTargetApp */); + pkg, uid, new ParceledListSlice(Arrays.asList(conversationChannel))); mRankingHandler.requestSort(); handleSavePolicyFile(); } diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 444fef634de3..1bbcc839ccd1 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -918,7 +918,7 @@ public class PreferencesHelper implements RankingConfig { throw new IllegalArgumentException("Reserved id"); } NotificationChannel existing = r.channels.get(channel.getId()); - if (existing != null) { + if (existing != null && fromTargetApp) { // Actually modifying an existing channel - keep most of the existing settings if (existing.isDeleted()) { // The existing channel was deleted - undelete it. @@ -1004,7 +1004,9 @@ public class PreferencesHelper implements RankingConfig { } if (fromTargetApp) { channel.setLockscreenVisibility(r.visibility); - channel.setAllowBubbles(NotificationChannel.DEFAULT_ALLOW_BUBBLE); + channel.setAllowBubbles(existing != null + ? existing.getAllowBubbles() + : NotificationChannel.DEFAULT_ALLOW_BUBBLE); } clearLockedFieldsLocked(channel); diff --git a/services/core/java/com/android/server/oemlock/OemLockService.java b/services/core/java/com/android/server/oemlock/OemLockService.java index bac89160ea5d..4c6110b99efd 100644 --- a/services/core/java/com/android/server/oemlock/OemLockService.java +++ b/services/core/java/com/android/server/oemlock/OemLockService.java @@ -25,7 +25,6 @@ import android.annotation.EnforcePermission; import android.annotation.Nullable; import android.app.ActivityManager; import android.content.Context; -import android.hardware.oemlock.V1_0.IOemLock; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; @@ -58,15 +57,18 @@ public class OemLockService extends SystemService { private OemLock mOemLock; public static boolean isHalPresent() { - return VendorLock.getOemLockHalService() != null; + return (VendorLockHidl.getOemLockHalService() != null) + || (VendorLockAidl.getOemLockHalService() != null); } /** Select the OEM lock implementation */ private static OemLock getOemLock(Context context) { - final IOemLock oemLockHal = VendorLock.getOemLockHalService(); - if (oemLockHal != null) { - Slog.i(TAG, "Using vendor lock via the HAL"); - return new VendorLock(context, oemLockHal); + if (VendorLockAidl.getOemLockHalService() != null) { + Slog.i(TAG, "Using vendor lock via the HAL(aidl)"); + return new VendorLockAidl(context); + } else if (VendorLockHidl.getOemLockHalService() != null) { + Slog.i(TAG, "Using vendor lock via the HAL(hidl)"); + return new VendorLockHidl(context); } else { Slog.i(TAG, "Using persistent data block based lock"); return new PersistentDataBlockLock(context); diff --git a/services/core/java/com/android/server/oemlock/VendorLockAidl.java b/services/core/java/com/android/server/oemlock/VendorLockAidl.java new file mode 100644 index 000000000000..82d45ab7c49c --- /dev/null +++ b/services/core/java/com/android/server/oemlock/VendorLockAidl.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.oemlock; + +import android.annotation.Nullable; +import android.content.Context; +import android.hardware.oemlock.IOemLock; +import android.hardware.oemlock.OemLockSecureStatus; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Slog; + +/** Uses the OEM lock HAL. */ +class VendorLockAidl extends OemLock { + private static final String TAG = "OemLock"; + private IOemLock mOemLock; + + static IOemLock getOemLockHalService() { + return IOemLock.Stub.asInterface( + ServiceManager.waitForDeclaredService(IOemLock.DESCRIPTOR + "/default")); + } + + VendorLockAidl(Context context) { + mOemLock = getOemLockHalService(); + } + + @Override + @Nullable + String getLockName() { + try { + return mOemLock.getName(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get name from HAL", e); + throw e.rethrowFromSystemServer(); + } + } + + @Override + void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) { + try { + final int status; + if (signature == null) { + status = mOemLock.setOemUnlockAllowedByCarrier(allowed, new byte[0]); + } else { + status = mOemLock.setOemUnlockAllowedByCarrier(allowed, signature); + } + switch (status) { + case OemLockSecureStatus.OK: + Slog.i(TAG, "Updated carrier allows OEM lock state to: " + allowed); + return; + + case OemLockSecureStatus.INVALID_SIGNATURE: + if (signature == null) { + throw new IllegalArgumentException("Signature required for carrier unlock"); + } + throw new SecurityException( + "Invalid signature used in attempt to carrier unlock"); + + default: + Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL"); + // Fallthrough + case OemLockSecureStatus.FAILED: + throw new RuntimeException("Failed to set carrier OEM unlock state"); + } + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set carrier state with HAL", e); + throw e.rethrowFromSystemServer(); + } + } + + @Override + boolean isOemUnlockAllowedByCarrier() { + try { + return mOemLock.isOemUnlockAllowedByCarrier(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get carrier state from HAL"); + throw e.rethrowFromSystemServer(); + } + } + + @Override + void setOemUnlockAllowedByDevice(boolean allowedByDevice) { + try { + mOemLock.setOemUnlockAllowedByDevice(allowedByDevice); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set device state with HAL", e); + throw e.rethrowFromSystemServer(); + } + } + + @Override + boolean isOemUnlockAllowedByDevice() { + + try { + return mOemLock.isOemUnlockAllowedByDevice(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get devie state from HAL"); + throw e.rethrowFromSystemServer(); + } + } +} diff --git a/services/core/java/com/android/server/oemlock/VendorLock.java b/services/core/java/com/android/server/oemlock/VendorLockHidl.java index 9c876da320a9..fe76787e8bd8 100644 --- a/services/core/java/com/android/server/oemlock/VendorLock.java +++ b/services/core/java/com/android/server/oemlock/VendorLockHidl.java @@ -27,10 +27,8 @@ import android.util.Slog; import java.util.ArrayList; import java.util.NoSuchElementException; -/** - * Uses the OEM lock HAL. - */ -class VendorLock extends OemLock { +/** Uses the OEM lock HAL. */ +class VendorLockHidl extends OemLock { private static final String TAG = "OemLock"; private Context mContext; @@ -40,29 +38,30 @@ class VendorLock extends OemLock { try { return IOemLock.getService(/* retry */ true); } catch (NoSuchElementException e) { - Slog.i(TAG, "OemLock HAL not present on device"); + Slog.i(TAG, "OemLock Hidl HAL not present on device"); return null; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } - VendorLock(Context context, IOemLock oemLock) { + VendorLockHidl(Context context) { mContext = context; - mOemLock = oemLock; + mOemLock = getOemLockHalService(); } @Override @Nullable String getLockName() { - final Integer[] requestStatus = new Integer[1]; final String[] lockName = new String[1]; + final Integer[] requestStatus = new Integer[1]; try { - mOemLock.getName((status, name) -> { - requestStatus[0] = status; - lockName[0] = name; - }); + mOemLock.getName( + (status, name) -> { + requestStatus[0] = status; + lockName[0] = name; + }); } catch (RemoteException e) { Slog.e(TAG, "Failed to get name from HAL", e); throw e.rethrowFromSystemServer(); @@ -113,14 +112,14 @@ class VendorLock extends OemLock { @Override boolean isOemUnlockAllowedByCarrier() { - final Integer[] requestStatus = new Integer[1]; final Boolean[] allowedByCarrier = new Boolean[1]; - + final Integer[] requestStatus = new Integer[1]; try { - mOemLock.isOemUnlockAllowedByCarrier((status, allowed) -> { - requestStatus[0] = status; - allowedByCarrier[0] = allowed; - }); + mOemLock.isOemUnlockAllowedByCarrier( + (status, allowed) -> { + requestStatus[0] = status; + allowedByCarrier[0] = allowed; + }); } catch (RemoteException e) { Slog.e(TAG, "Failed to get carrier state from HAL"); throw e.rethrowFromSystemServer(); @@ -161,14 +160,15 @@ class VendorLock extends OemLock { @Override boolean isOemUnlockAllowedByDevice() { - final Integer[] requestStatus = new Integer[1]; final Boolean[] allowedByDevice = new Boolean[1]; + final Integer[] requestStatus = new Integer[1]; try { - mOemLock.isOemUnlockAllowedByDevice((status, allowed) -> { - requestStatus[0] = status; - allowedByDevice[0] = allowed; - }); + mOemLock.isOemUnlockAllowedByDevice( + (status, allowed) -> { + requestStatus[0] = status; + allowedByDevice[0] = allowed; + }); } catch (RemoteException e) { Slog.e(TAG, "Failed to get devie state from HAL"); throw e.rethrowFromSystemServer(); diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index dd4183024314..cda7503400c7 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -92,6 +92,8 @@ public final class BackgroundDexOptService { new ComponentName("android", BackgroundDexOptJobService.class.getName()); // Possible return codes of individual optimization steps. + /** Initial value. */ + public static final int STATUS_UNSPECIFIED = -1; /** Ok status: Optimizations finished, All packages were processed, can continue */ public static final int STATUS_OK = 0; /** Optimizations should be aborted. Job scheduler requested it. */ @@ -108,16 +110,20 @@ public final class BackgroundDexOptService { * job will exclude those failed packages. */ public static final int STATUS_DEX_OPT_FAILED = 5; + /** Encountered fatal error, such as a runtime exception. */ + public static final int STATUS_FATAL_ERROR = 6; @IntDef(prefix = {"STATUS_"}, value = { + STATUS_UNSPECIFIED, STATUS_OK, STATUS_ABORT_BY_CANCELLATION, STATUS_ABORT_NO_SPACE_LEFT, STATUS_ABORT_THERMAL, STATUS_ABORT_BATTERY, STATUS_DEX_OPT_FAILED, + STATUS_FATAL_ERROR, }) @Retention(RetentionPolicy.SOURCE) public @interface Status {} @@ -153,7 +159,7 @@ public final class BackgroundDexOptService { // True if JobScheduler invocations of dexopt have been disabled. @GuardedBy("mLock") private boolean mDisableJobSchedulerJobs; - @GuardedBy("mLock") @Status private int mLastExecutionStatus = STATUS_OK; + @GuardedBy("mLock") @Status private int mLastExecutionStatus = STATUS_UNSPECIFIED; @GuardedBy("mLock") private long mLastExecutionStartUptimeMs; @GuardedBy("mLock") private long mLastExecutionDurationMs; @@ -561,18 +567,26 @@ public final class BackgroundDexOptService { private boolean runIdleOptimization( PackageManagerService pm, List<String> pkgs, boolean isPostBootUpdate) { synchronized (mLock) { + mLastExecutionStatus = STATUS_UNSPECIFIED; mLastExecutionStartUptimeMs = SystemClock.uptimeMillis(); mLastExecutionDurationMs = -1; } - long lowStorageThreshold = getLowStorageThreshold(); - int status = idleOptimizePackages(pm, pkgs, lowStorageThreshold, isPostBootUpdate); - logStatus(status); - synchronized (mLock) { - mLastExecutionStatus = status; - mLastExecutionDurationMs = SystemClock.uptimeMillis() - mLastExecutionStartUptimeMs; - } - return status == STATUS_OK || status == STATUS_DEX_OPT_FAILED; + int status = STATUS_UNSPECIFIED; + try { + long lowStorageThreshold = getLowStorageThreshold(); + status = idleOptimizePackages(pm, pkgs, lowStorageThreshold, isPostBootUpdate); + logStatus(status); + return status == STATUS_OK || status == STATUS_DEX_OPT_FAILED; + } catch (RuntimeException e) { + status = STATUS_FATAL_ERROR; + throw e; + } finally { + synchronized (mLock) { + mLastExecutionStatus = status; + mLastExecutionDurationMs = SystemClock.uptimeMillis() - mLastExecutionStartUptimeMs; + } + } } /** Gets the size of the directory. It uses recursion to go over all files. */ diff --git a/services/core/java/com/android/server/pm/UserVisibilityMediator.java b/services/core/java/com/android/server/pm/UserVisibilityMediator.java index 9c4187b35e93..2650b2394cc5 100644 --- a/services/core/java/com/android/server/pm/UserVisibilityMediator.java +++ b/services/core/java/com/android/server/pm/UserVisibilityMediator.java @@ -413,41 +413,12 @@ public final class UserVisibilityMediator implements Dumpable { if (displayId == Display.INVALID_DISPLAY) { return false; } - if (!mUsersOnSecondaryDisplaysEnabled) { - return isCurrentUserOrRunningProfileOfCurrentUser(userId); - } - // TODO(b/256242848): temporary workaround to let WM use this API without breaking current - // behavior - return true for current user / profile for any display (other than those - // explicitly assigned to another users), otherwise they wouldn't be able to launch - // activities on other non-passenger displays, like cluster). - // In the long-term, it should rely just on mUsersOnSecondaryDisplays, which - // would be updated by CarService to allow additional mappings. - if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) { - synchronized (mLock) { - boolean assignedToUser = false; - boolean assignedToAnotherUser = false; - for (int i = 0; i < mUsersOnSecondaryDisplays.size(); i++) { - if (mUsersOnSecondaryDisplays.valueAt(i) == displayId) { - if (mUsersOnSecondaryDisplays.keyAt(i) == userId) { - assignedToUser = true; - break; - } else { - assignedToAnotherUser = true; - // Cannot break because it could be assigned to a profile of the user - // (and we better not assume that the iteration will check for the - // parent user before its profiles) - } - } - } - if (DBG) { - Slogf.d(TAG, "isUserVisibleOnDisplay(%d, %d): assignedToUser=%b, " - + "assignedToAnotherUser=%b, mUsersOnSecondaryDisplays=%s", - userId, displayId, assignedToUser, assignedToAnotherUser, - mUsersOnSecondaryDisplays); - } - return assignedToUser || !assignedToAnotherUser; - } + if (!mUsersOnSecondaryDisplaysEnabled || displayId == Display.DEFAULT_DISPLAY) { + // TODO(b/245939659): will need to move the displayId == Display.DEFAULT_DISPLAY outside + // once it supports background users on DEFAULT_DISPLAY (for example, passengers in a + // no-driver configuration) + return isCurrentUserOrRunningProfileOfCurrentUser(userId); } synchronized (mLock) { diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java index 14075301d523..f388e070bb85 100644 --- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java +++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java @@ -303,7 +303,9 @@ public class ArtStatsLogUtils { } private static final Map<Integer, Integer> STATUS_MAP = - Map.of(BackgroundDexOptService.STATUS_OK, + Map.of(BackgroundDexOptService.STATUS_UNSPECIFIED, + ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_UNKNOWN, + BackgroundDexOptService.STATUS_OK, ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_JOB_FINISHED, BackgroundDexOptService.STATUS_ABORT_BY_CANCELLATION, ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_ABORT_BY_CANCELLATION, @@ -314,7 +316,9 @@ public class ArtStatsLogUtils { BackgroundDexOptService.STATUS_ABORT_BATTERY, ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_ABORT_BATTERY, BackgroundDexOptService.STATUS_DEX_OPT_FAILED, - ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_JOB_FINISHED); + ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_JOB_FINISHED, + BackgroundDexOptService.STATUS_FATAL_ERROR, + ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_FATAL_ERROR); /** Helper class to write background dexopt job stats to statsd. */ public static class BackgroundDexoptJobStatsLogger { diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java index 0409a8416dc3..111b4f6ee2a1 100644 --- a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java +++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java @@ -109,7 +109,7 @@ public final class ConfigurationInternal { * testing only. See {@link #isGeoDetectionExecutionEnabled()} and {@link #getDetectionMode()} * for details. */ - boolean getGeoDetectionRunInBackgroundEnabled() { + boolean getGeoDetectionRunInBackgroundEnabledSetting() { return mGeoDetectionRunInBackgroundEnabled; } @@ -132,7 +132,7 @@ public final class ConfigurationInternal { * from the raw setting value. */ public boolean getAutoDetectionEnabledBehavior() { - return isAutoDetectionSupported() && mAutoDetectionEnabledSetting; + return isAutoDetectionSupported() && getAutoDetectionEnabledSetting(); } /** Returns the ID of the user this configuration is associated with. */ @@ -171,27 +171,55 @@ public final class ConfigurationInternal { * time zone. */ public @DetectionMode int getDetectionMode() { - if (!getAutoDetectionEnabledBehavior()) { + if (!isAutoDetectionSupported()) { + // Handle the easy case first: No auto detection algorithms supported must mean manual. return DETECTION_MODE_MANUAL; - } else if (isGeoDetectionSupported() && getLocationEnabledSetting() - && getGeoDetectionEnabledSetting()) { + } else if (!getAutoDetectionEnabledSetting()) { + // Auto detection algorithms are supported, but disabled by the user. + return DETECTION_MODE_MANUAL; + } else if (getGeoDetectionEnabledBehavior()) { return DETECTION_MODE_GEO; - } else { + } else if (isTelephonyDetectionSupported()) { return DETECTION_MODE_TELEPHONY; + } else { + // On devices with telephony detection support, telephony is used instead of geo when + // geo cannot be used. This "unknown" case can occur on devices with only the location + // detection algorithm supported when the user's master location setting prevents its + // use. + return DETECTION_MODE_UNKNOWN; } } + private boolean getGeoDetectionEnabledBehavior() { + // isAutoDetectionSupported() should already have been checked before calling this method. + if (isGeoDetectionSupported() && getLocationEnabledSetting()) { + if (isTelephonyDetectionSupported()) { + // This is the "normal" case for smartphones that have both telephony and geo + // detection: the user chooses which type of detection to use. + return getGeoDetectionEnabledSetting(); + } else { + // When only geo detection is supported then there is no choice for the user to + // make between detection modes, so no user setting is consulted. + return true; + } + } + return false; + } + /** * Returns true if geolocation time zone detection behavior can execute. Typically, this will * agree with {@link #getDetectionMode()}, but under rare circumstances the geolocation detector - * may be run in the background if the user's settings allow. See also {@link - * #getGeoDetectionRunInBackgroundEnabled()}. + * may be run in the background if the user's settings allow. */ public boolean isGeoDetectionExecutionEnabled() { + return getDetectionMode() == DETECTION_MODE_GEO + || getGeoDetectionRunInBackgroundEnabledBehavior(); + } + + private boolean getGeoDetectionRunInBackgroundEnabledBehavior() { return isGeoDetectionSupported() && getLocationEnabledSetting() - && ((mAutoDetectionEnabledSetting && getGeoDetectionEnabledSetting()) - || getGeoDetectionRunInBackgroundEnabled()); + && getGeoDetectionRunInBackgroundEnabledSetting(); } @NonNull @@ -216,11 +244,19 @@ public final class ConfigurationInternal { builder.setConfigureAutoDetectionEnabledCapability(configureAutoDetectionEnabledCapability); boolean deviceHasLocationTimeZoneDetection = isGeoDetectionSupported(); + boolean deviceHasTelephonyDetection = isTelephonyDetectionSupported(); + // Note: allowConfigDateTime does not restrict the ability to change location time zone // detection enabled. This is intentional as it has user privacy implications and so it - // makes sense to leave this under a user's control. + // makes sense to leave this under a user's control. The only time this is not true is + // on devices that only support location-based detection and the main auto detection setting + // is used to influence whether location can be used. final @CapabilityState int configureGeolocationDetectionEnabledCapability; - if (!deviceHasLocationTimeZoneDetection) { + if (!deviceHasLocationTimeZoneDetection || !deviceHasTelephonyDetection) { + // If the device doesn't have geolocation detection support OR it ONLY has geolocation + // detection support (no telephony) then the user doesn't need the ability to toggle the + // location-based detection on and off (the auto detection toggle is considered + // sufficient). configureGeolocationDetectionEnabledCapability = CAPABILITY_NOT_SUPPORTED; } else if (!mAutoDetectionEnabledSetting || !getLocationEnabledSetting()) { configureGeolocationDetectionEnabledCapability = CAPABILITY_NOT_APPLICABLE; diff --git a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java index aad53596fc19..59691f8a30c5 100644 --- a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java +++ b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java @@ -136,7 +136,7 @@ public final class MetricsTimeZoneDetectorState { * testing only. */ public boolean getGeoDetectionRunInBackgroundEnabled() { - return mConfigurationInternal.getGeoDetectionRunInBackgroundEnabled(); + return mConfigurationInternal.getGeoDetectionRunInBackgroundEnabledSetting(); } /** Returns true if enhanced metric collection is enabled. */ diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java index 295c5c8ad373..6ebaf14c28db 100644 --- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java +++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java @@ -279,15 +279,18 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { final boolean autoDetectionEnabled = configuration.isAutoDetectionEnabled(); setAutoDetectionEnabledIfRequired(autoDetectionEnabled); - // Avoid writing the geo detection enabled setting for devices with settings that - // are currently overridden by server flags: otherwise we might overwrite a droidfood - // user's real setting permanently. - // Also avoid writing the geo detection enabled setting for devices that do not support - // geo time zone detection: if we wrote it down then we'd set the value explicitly, - // which would prevent detecting "default" later. That might influence what happens on - // later releases that start to support geo detection on the same hardware. + // Only write the geo detection enabled setting when its values is used, e.g.: + // 1) Devices with a setting value that is not currently overridden by server flags + // 2) Devices that support both telephony and location detection algorithms + // + // If we wrote a setting value down when it's not used then we'd be setting the value + // explicitly, which would prevent detecting the setting is in "default" state later. + // Not being able to detect if the user has actually expressed a preference could + // influence what happens on later releases that start to support geo detection on the + // user's same hardware. if (!getGeoDetectionSettingEnabledOverride().isPresent() - && isGeoTimeZoneDetectionFeatureSupported()) { + && isGeoTimeZoneDetectionFeatureSupported() + && isTelephonyTimeZoneDetectionFeatureSupported()) { final boolean geoDetectionEnabledSetting = configuration.isGeoDetectionEnabled(); setGeoDetectionEnabledSettingIfRequired(userId, geoDetectionEnabledSetting); } diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java index 3424251ea57f..fa811efcfec0 100644 --- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java @@ -47,6 +47,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.SystemTimeZone.TimeZoneConfidence; +import com.android.server.timezonedetector.ConfigurationInternal.DetectionMode; import java.io.PrintWriter; import java.time.Duration; @@ -597,9 +598,10 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat @GuardedBy("this") private void doAutoTimeZoneDetection( @NonNull ConfigurationInternal currentUserConfig, @NonNull String detectionReason) { - // Use the correct algorithm based on the user's current configuration. If it changes, then - // detection will be re-run. - switch (currentUserConfig.getDetectionMode()) { + // Use the correct detection algorithm based on the device's config and the user's current + // configuration. If user config changes, then detection will be re-run. + @DetectionMode int detectionMode = currentUserConfig.getDetectionMode(); + switch (detectionMode) { case ConfigurationInternal.DETECTION_MODE_MANUAL: // No work to do. break; @@ -635,9 +637,14 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat case ConfigurationInternal.DETECTION_MODE_TELEPHONY: doTelephonyTimeZoneDetection(detectionReason); break; + case ConfigurationInternal.DETECTION_MODE_UNKNOWN: + // The "DETECTION_MODE_UNKNOWN" state can occur on devices with only location + // detection algorithm support and when the user's master location toggle is off. + Slog.i(LOG_TAG, "Unknown detection mode: " + detectionMode + ", is location off?"); + break; default: - Slog.wtf(LOG_TAG, "Unknown detection mode: " - + currentUserConfig.getDetectionMode()); + // Coding error + Slog.wtf(LOG_TAG, "Unknown detection mode: " + detectionMode); } } @@ -1043,15 +1050,31 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat TelephonyTimeZoneAlgorithmStatus telephonyAlgorithmStatus = createTelephonyAlgorithmStatus(currentConfigurationInternal); - LocationTimeZoneAlgorithmStatus locationAlgorithmStatus = - latestLocationAlgorithmEvent == null ? LocationTimeZoneAlgorithmStatus.UNKNOWN - : latestLocationAlgorithmEvent.getAlgorithmStatus(); + LocationTimeZoneAlgorithmStatus locationAlgorithmStatus = createLocationAlgorithmStatus( + currentConfigurationInternal, latestLocationAlgorithmEvent); return new TimeZoneDetectorStatus( detectorStatus, telephonyAlgorithmStatus, locationAlgorithmStatus); } @NonNull + private static LocationTimeZoneAlgorithmStatus createLocationAlgorithmStatus( + ConfigurationInternal currentConfigurationInternal, + LocationAlgorithmEvent latestLocationAlgorithmEvent) { + LocationTimeZoneAlgorithmStatus locationAlgorithmStatus; + if (latestLocationAlgorithmEvent != null) { + locationAlgorithmStatus = latestLocationAlgorithmEvent.getAlgorithmStatus(); + } else if (!currentConfigurationInternal.isGeoDetectionSupported()) { + locationAlgorithmStatus = LocationTimeZoneAlgorithmStatus.NOT_SUPPORTED; + } else if (currentConfigurationInternal.isGeoDetectionExecutionEnabled()) { + locationAlgorithmStatus = LocationTimeZoneAlgorithmStatus.RUNNING_NOT_REPORTED; + } else { + locationAlgorithmStatus = LocationTimeZoneAlgorithmStatus.NOT_RUNNING; + } + return locationAlgorithmStatus; + } + + @NonNull private static TelephonyTimeZoneAlgorithmStatus createTelephonyAlgorithmStatus( @NonNull ConfigurationInternal currentConfigurationInternal) { int algorithmStatus; diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 5d084616bfea..f74956b7c846 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -1559,9 +1559,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub try { mReply.sendResult(null); } catch (RemoteException e) { - Slog.d(TAG, "failed to send callback!", e); - } finally { Binder.restoreCallingIdentity(ident); + Slog.d(TAG, "failed to send callback!", e); } t.traceEnd(); mReply = null; diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 715729310a06..af430f99cf58 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -614,17 +614,18 @@ class ActivityClientController extends IActivityClientController.Stub { } /** - * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not - * found. + * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if + * the task {@link Configuration} cannot be obtained. */ @Override - public int getTaskWindowingMode(IBinder activityToken) { + @Nullable + public Configuration getTaskConfiguration(IBinder activityToken) { synchronized (mGlobalLock) { final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken); if (ar == null) { - return -1; + return null; } - return ar.getTask().getWindowingMode(); + return ar.getTask().getConfiguration(); } } diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index c49d6729effc..56aae2d6db37 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -559,47 +559,52 @@ public class ActivityStartController { final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea() .getRootTask(WINDOWING_MODE_UNDEFINED, activityType); if (rootTask == null) return false; + final RemoteTransition remote = options.getRemoteTransition(); final ActivityRecord r = rootTask.topRunningActivity(); - if (r == null || r.mVisibleRequested || !r.attachedToProcess() + if (r == null || r.mVisibleRequested || !r.attachedToProcess() || remote == null || !r.mActivityComponent.equals(intent.getComponent()) // Recents keeps invisible while device is locked. || r.mDisplayContent.isKeyguardLocked()) { return false; } mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r); - final RemoteTransition remote = options.getRemoteTransition(); - if (remote != null && rootTask.mTransitionController.isCollecting()) { - final Transition transition = new Transition(WindowManager.TRANSIT_TO_FRONT, - 0 /* flags */, rootTask.mTransitionController, - mService.mWindowManager.mSyncEngine); + final ActivityMetricsLogger.LaunchingState launchingState = + mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent); + final Transition transition = new Transition(WindowManager.TRANSIT_TO_FRONT, + 0 /* flags */, r.mTransitionController, mService.mWindowManager.mSyncEngine); + if (r.mTransitionController.isCollecting()) { // Special case: we are entering recents while an existing transition is running. In // this case, we know it's safe to "defer" the activity launch, so lets do so now so // that it can get its own transition and thus update launcher correctly. mService.mWindowManager.mSyncEngine.queueSyncSet( - () -> rootTask.mTransitionController.moveToCollecting(transition), () -> { - final Task task = r.getTask(); - task.mTransitionController.requestStartTransition(transition, - task, remote, null /* displayChange */); - task.mTransitionController.collect(task); - startExistingRecentsIfPossibleInner(intent, options, r, task, rootTask); + if (r.isAttached()) { + r.mTransitionController.moveToCollecting(transition); + } + }, + () -> { + if (r.isAttached() && transition.isCollecting()) { + startExistingRecentsIfPossibleInner(options, r, rootTask, + launchingState, remote, transition); + } }); } else { - final Task task = r.getTask(); - task.mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_TO_FRONT, - 0 /* flags */, task, task /* readyGroupRef */, - options.getRemoteTransition(), null /* displayChange */); - startExistingRecentsIfPossibleInner(intent, options, r, task, rootTask); + r.mTransitionController.moveToCollecting(transition); + startExistingRecentsIfPossibleInner(options, r, rootTask, launchingState, remote, + transition); } return true; } - void startExistingRecentsIfPossibleInner(Intent intent, ActivityOptions options, - ActivityRecord r, Task task, Task rootTask) { - final ActivityMetricsLogger.LaunchingState launchingState = - mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent); + private void startExistingRecentsIfPossibleInner(ActivityOptions options, ActivityRecord r, + Task rootTask, ActivityMetricsLogger.LaunchingState launchingState, + RemoteTransition remoteTransition, Transition transition) { + final Task task = r.getTask(); mService.deferWindowLayout(); try { + r.mTransitionController.requestStartTransition(transition, + task, remoteTransition, null /* displayChange */); + r.mTransitionController.collect(task); r.mTransitionController.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask)); task.moveToFront("startExistingRecents"); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 97aee0bd0bad..5938e7f095ea 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1388,9 +1388,9 @@ class ActivityStarter { && transitionController.getTransitionPlayer() != null) ? transitionController.createTransition(TRANSIT_OPEN) : null; RemoteTransition remoteTransition = r.takeRemoteTransition(); - transitionController.collect(r); try { mService.deferWindowLayout(); + transitionController.collect(r); try { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner"); result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 94d4ddeb465c..2e5ab1a7bfe1 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -441,6 +441,7 @@ class SurfaceAnimationRunner { .setPixelFormat(PixelFormat.RGBA_8888) .setChildrenOnly(true) .setAllowProtected(true) + .setCaptureSecureLayers(true) .build(); final ScreenCapture.ScreenshotHardwareBuffer edgeBuffer = ScreenCapture.captureLayers(captureArgs); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 4e7fe0e71420..356cbdacbed6 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1587,9 +1587,9 @@ class Task extends TaskFragment { } else { // Finish or destroy apps from the bottom to ensure that all the other activity have // been finished and the top task in another task gets resumed when a top activity is - // removed. Otherwise, shell transitions wouldn't run because there would be no event - // that sets the transition ready. - final boolean traverseTopToBottom = !mTransitionController.isShellTransitionsEnabled(); + // removed. Otherwise, the next top activity could be started while the top activity + // is removed, which is not necessary since the next top activity is on the same Task + // and should also be removed. forAllActivities((r) -> { if (r.finishing || (excludingTaskOverlay && r.isTaskOverlay())) { return; @@ -1603,7 +1603,7 @@ class Task extends TaskFragment { } else { r.destroyIfPossible(reason); } - }, traverseTopToBottom); + }, false /* traverseTopToBottom */); } } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 4f91c54df4ca..b277804ed230 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -338,7 +338,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe return mFinishTransaction; } - private boolean isCollecting() { + boolean isCollecting() { return mState == STATE_COLLECTING || mState == STATE_STARTED; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 42cd8c11fec2..6032f874dd75 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2553,6 +2553,12 @@ public class WindowManagerService extends IWindowManager.Stub && win.mSyncSeqId > lastSyncSeqId) { maybeSyncSeqId = win.shouldSyncWithBuffers() ? win.mSyncSeqId : -1; win.markRedrawForSyncReported(); + if (win.mSyncState == WindowContainer.SYNC_STATE_WAITING_FOR_DRAW + && winAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN + && maybeSyncSeqId < 0) { + // Do not wait for a drawn window which won't report draw. + win.onSyncFinishedDrawing(); + } } else { maybeSyncSeqId = -1; } diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java index 374da1c8e7e3..30fcd06327dd 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java @@ -22,10 +22,11 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageManager; +import android.credentials.ClearCredentialStateRequest; import android.credentials.CreateCredentialRequest; import android.credentials.GetCredentialOption; import android.credentials.GetCredentialRequest; -import android.credentials.IClearCredentialSessionCallback; +import android.credentials.IClearCredentialStateCallback; import android.credentials.ICreateCredentialCallback; import android.credentials.ICredentialManager; import android.credentials.IGetCredentialCallback; @@ -206,8 +207,8 @@ public final class CredentialManagerService extends } @Override - public ICancellationSignal clearCredentialSession( - IClearCredentialSessionCallback callback, String callingPackage) { + public ICancellationSignal clearCredentialState(ClearCredentialStateRequest request, + IClearCredentialStateCallback callback, String callingPackage) { // TODO: implement. Log.i(TAG, "clearCredentialSession"); ICancellationSignal cancelTransport = CancellationSignal.createTransport(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java index aad82cdf3254..5fc3cb00e57f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java @@ -80,7 +80,7 @@ final class PolicyState<V> { private boolean resolvePolicy() { V resolvedPolicy = mPolicyDefinition.resolvePolicy(mAdminsPolicy); - boolean policyChanged = Objects.equals(resolvedPolicy, mCurrentResolvedPolicy); + boolean policyChanged = !Objects.equals(resolvedPolicy, mCurrentResolvedPolicy); mCurrentResolvedPolicy = resolvedPolicy; return policyChanged; diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java index 693f3a0cf8a0..1bd5031d6c69 100644 --- a/services/people/java/com/android/server/people/data/DataManager.java +++ b/services/people/java/com/android/server/people/data/DataManager.java @@ -788,7 +788,7 @@ public class DataManager { private void updateDefaultSmsApp(@NonNull UserData userData) { ComponentName component = SmsApplication.getDefaultSmsApplicationAsUser( - mContext, /* updateIfNeeded= */ false, userData.getUserId()); + mContext, /* updateIfNeeded= */ false, UserHandle.of(userData.getUserId())); String defaultSmsApp = component != null ? component.getPackageName() : null; userData.setDefaultSmsApp(defaultSmsApp); } diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java index 298cbf3e61b9..6af726910226 100644 --- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java +++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java @@ -74,6 +74,7 @@ import android.annotation.Nullable; import android.app.Application; import android.app.IBackupAgent; import android.app.backup.BackupAgent; +import android.app.backup.BackupAnnotations; import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; import android.app.backup.BackupManager; @@ -183,7 +184,7 @@ public class KeyValueBackupTaskTest { private static final String BACKUP_AGENT_SHARED_PREFS_SYNCHRONIZER_CLASS = "android.app.backup.BackupAgent$SharedPrefsSynchronizer"; private static final int USER_ID = 10; - private static final int OPERATION_TYPE = BackupManager.OperationType.BACKUP; + private static final int BACKUP_DESTINATION = BackupAnnotations.BackupDestination.CLOUD; @Mock private TransportManager mTransportManager; @Mock private DataChangedJournal mOldJournal; @@ -264,7 +265,8 @@ public class KeyValueBackupTaskTest { LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal); mBackupEligibilityRules = new BackupEligibilityRules(mPackageManager, - LocalServices.getService(PackageManagerInternal.class), USER_ID, OPERATION_TYPE); + LocalServices.getService(PackageManagerInternal.class), USER_ID, + BACKUP_DESTINATION); } @After diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index 55d116043f15..9234431accb9 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -439,14 +439,25 @@ public class MockingOomAdjusterTests { @SuppressWarnings("GuardedBy") @Test public void testUpdateOomAdj_DoOne_FgService_ShortFgs() { + sService.mConstants.TOP_TO_FGS_GRACE_DURATION = 100_000; + sService.mConstants.mShortFgsProcStateExtraWaitDuration = 200_000; + + ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(sService); + s.startRequested = true; + s.isForeground = true; + s.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; + s.setShortFgsInfo(SystemClock.uptimeMillis()); + // SHORT_SERVICE FGS will get IMP_FG and a slightly different recent-adjustment. { ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); + app.mServices.startService(s); app.mServices.setHasForegroundServices(true, ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false); app.mState.setLastTopTime(SystemClock.uptimeMillis()); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE); assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND, @@ -461,9 +472,11 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); app.mServices.setHasForegroundServices(true, ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false); + app.mServices.startService(s); app.mState.setLastTopTime(SystemClock.uptimeMillis() - sService.mConstants.TOP_TO_FGS_GRACE_DURATION); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE); assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND, @@ -471,6 +484,33 @@ public class MockingOomAdjusterTests { // Still should get network access. assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) != 0); } + + // SHORT_SERVICE, timed out already. + s = ServiceRecord.newEmptyInstanceForTest(sService); + s.startRequested = true; + s.isForeground = true; + s.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; + s.setShortFgsInfo(SystemClock.uptimeMillis() + - sService.mConstants.mShortFgsTimeoutDuration + - sService.mConstants.mShortFgsProcStateExtraWaitDuration); + { + ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, + MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); + app.mServices.setHasForegroundServices(true, + ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false); + app.mServices.startService(s); + app.mState.setLastTopTime(SystemClock.uptimeMillis() + - sService.mConstants.TOP_TO_FGS_GRACE_DURATION); + sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + + sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE); + + // Procstate should be lower than FGS. (It should be SERVICE) + assertEquals(app.mState.getSetProcState(), PROCESS_STATE_SERVICE); + + // Shouldn't have the network capability now. + assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) == 0); + } } @SuppressWarnings("GuardedBy") diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java b/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java index afcedd6f41bf..a97491daa96e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java @@ -40,7 +40,6 @@ public final class AsyncUserVisibilityListener implements UserVisibilityListener private static final String TAG = AsyncUserVisibilityListener.class.getSimpleName(); private static final long WAIT_TIMEOUT_MS = 2_000; - private static final long WAIT_NO_EVENTS_TIMEOUT_MS = 100; private static int sNextId; diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java index 1be7e2e6e30e..5c3d69547755 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java @@ -17,6 +17,7 @@ package com.android.server.pm; import static com.android.server.pm.BackgroundDexOptService.STATUS_DEX_OPT_FAILED; +import static com.android.server.pm.BackgroundDexOptService.STATUS_FATAL_ERROR; import static com.android.server.pm.BackgroundDexOptService.STATUS_OK; import static com.google.common.truth.Truth.assertThat; @@ -24,6 +25,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -264,6 +266,20 @@ public final class BackgroundDexOptServiceUnitTest { } @Test + public void testIdleJobFullRunWithFatalError() { + initUntilBootCompleted(); + runFullJob(mJobServiceForPostBoot, mJobParametersForPostBoot, + /* expectedReschedule= */ false, /* expectedStatus= */ STATUS_OK, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ null); + + doThrow(RuntimeException.class).when(mDexOptHelper).performDexOptWithStatus(any()); + + runFullJob(mJobServiceForIdle, mJobParametersForIdle, + /* expectedReschedule= */ false, /* expectedStatus= */ STATUS_FATAL_ERROR, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ null); + } + + @Test public void testSystemReadyWhenDisabled() { when(mInjector.isBackgroundDexOptDisabled()).thenReturn(true); @@ -510,13 +526,21 @@ public final class BackgroundDexOptServiceUnitTest { ArgumentCaptor<Runnable> argThreadRunnable = ArgumentCaptor.forClass(Runnable.class); verify(mInjector, atLeastOnce()).createAndStartThread(any(), argThreadRunnable.capture()); - argThreadRunnable.getValue().run(); + try { + argThreadRunnable.getValue().run(); + } catch (RuntimeException e) { + if (expectedStatus != STATUS_FATAL_ERROR) { + throw e; + } + } verify(jobService, times(totalJobFinishedWithParams)).jobFinished(params, expectedReschedule); // Never block verify(mDexOptHelper, never()).controlDexOptBlocking(true); - verifyPerformDexOpt(); + if (expectedStatus != STATUS_FATAL_ERROR) { + verifyPerformDexOpt(); + } assertThat(getLastExecutionStatus()).isEqualTo(expectedStatus); } diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java index c5a85721cc8a..6d8910eb8cdd 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java @@ -15,12 +15,14 @@ */ package com.android.server.pm; +import static android.os.UserHandle.USER_NULL; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE; import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE; import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE; +import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible; import static com.android.server.pm.UserVisibilityChangedEvent.onVisible; import static com.android.server.pm.UserVisibilityMediator.INITIAL_CURRENT_USER_ID; @@ -40,6 +42,88 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator } @Test + public void testStartFgUser_onDefaultDisplay() throws Exception { + AsyncUserVisibilityListener listener = addListenerForEvents( + onInvisible(INITIAL_CURRENT_USER_ID), + onVisible(USER_ID)); + + int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG, + DEFAULT_DISPLAY); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); + + expectUserIsVisible(USER_ID); + expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY); + expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY); + expectUserIsNotVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID); + expectVisibleUsers(USER_ID); + + expectDisplayAssignedToUser(USER_ID, DEFAULT_DISPLAY); + expectUserAssignedToDisplay(DEFAULT_DISPLAY, USER_ID); + expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID); + expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID); + + expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY); + + listener.verify(); + } + + @Test + public void testSwitchFgUser_onDefaultDisplay() throws Exception { + int previousCurrentUserId = OTHER_USER_ID; + int currentUserId = USER_ID; + AsyncUserVisibilityListener listener = addListenerForEvents( + onInvisible(INITIAL_CURRENT_USER_ID), + onVisible(previousCurrentUserId), + onInvisible(previousCurrentUserId), + onVisible(currentUserId)); + startForegroundUser(previousCurrentUserId); + + int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG, + DEFAULT_DISPLAY); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); + + expectUserIsVisible(currentUserId); + expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY); + expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY); + expectUserIsNotVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID); + expectVisibleUsers(currentUserId); + + expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY); + expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId); + expectUserAssignedToDisplay(INVALID_DISPLAY, currentUserId); + expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, currentUserId); + + expectUserIsNotVisibleAtAll(previousCurrentUserId); + expectNoDisplayAssignedToUser(previousCurrentUserId); + + listener.verify(); + } + + @Test + public void testStartBgProfile_onDefaultDisplay_whenParentIsCurrentUser() throws Exception { + AsyncUserVisibilityListener listener = addListenerForEvents( + onInvisible(INITIAL_CURRENT_USER_ID), + onVisible(PARENT_USER_ID), + onVisible(PROFILE_USER_ID)); + startForegroundUser(PARENT_USER_ID); + + int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, + DEFAULT_DISPLAY); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); + + expectUserIsVisible(PROFILE_USER_ID); + expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY); + expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); + expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); + expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID); + + expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY); + expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID); + + listener.verify(); + } + + @Test public void testStartFgUser_onInvalidDisplay() throws Exception { AsyncUserVisibilityListener listener = addListenerForNoEvents(); @@ -89,15 +173,15 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator startDefaultProfile(); // Make sure they were visible before - expectUserIsVisibleOnDisplay(PARENT_USER_ID, SECONDARY_DISPLAY_ID); - expectUserIsVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); + expectUserIsNotVisibleOnDisplay("before", PARENT_USER_ID, SECONDARY_DISPLAY_ID); + expectUserIsNotVisibleOnDisplay("before", PROFILE_USER_ID, SECONDARY_DISPLAY_ID); int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG, SECONDARY_DISPLAY_ID); assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); - expectUserIsNotVisibleOnDisplay(PARENT_USER_ID, SECONDARY_DISPLAY_ID); - expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); + expectUserIsNotVisibleOnDisplay("after", PARENT_USER_ID, SECONDARY_DISPLAY_ID); + expectUserIsNotVisibleOnDisplay("after", PROFILE_USER_ID, SECONDARY_DISPLAY_ID); } @Test diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java index fc0287f5d638..1065392be8ce 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java @@ -15,7 +15,15 @@ */ package com.android.server.pm; +import static android.os.UserHandle.USER_NULL; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.Display.INVALID_DISPLAY; + import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE; +import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE; +import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible; +import static com.android.server.pm.UserVisibilityChangedEvent.onVisible; +import static com.android.server.pm.UserVisibilityMediator.INITIAL_CURRENT_USER_ID; import org.junit.Test; @@ -33,6 +41,88 @@ public final class UserVisibilityMediatorSUSDTest extends UserVisibilityMediator } @Test + public void testStartFgUser_onDefaultDisplay() throws Exception { + AsyncUserVisibilityListener listener = addListenerForEvents( + onInvisible(INITIAL_CURRENT_USER_ID), + onVisible(USER_ID)); + + int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG, + DEFAULT_DISPLAY); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); + + expectUserIsVisible(USER_ID); + expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY); + expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY); + expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID); + expectVisibleUsers(USER_ID); + + expectDisplayAssignedToUser(USER_ID, DEFAULT_DISPLAY); + expectUserAssignedToDisplay(DEFAULT_DISPLAY, USER_ID); + expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID); + expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID); + + expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY); + + listener.verify(); + } + + @Test + public void testSwitchFgUser_onDefaultDisplay() throws Exception { + int previousCurrentUserId = OTHER_USER_ID; + int currentUserId = USER_ID; + AsyncUserVisibilityListener listener = addListenerForEvents( + onInvisible(INITIAL_CURRENT_USER_ID), + onVisible(previousCurrentUserId), + onInvisible(previousCurrentUserId), + onVisible(currentUserId)); + startForegroundUser(previousCurrentUserId); + + int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG, + DEFAULT_DISPLAY); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); + + expectUserIsVisible(currentUserId); + expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY); + expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY); + expectUserIsVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID); + expectVisibleUsers(currentUserId); + + expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY); + expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId); + expectUserAssignedToDisplay(INVALID_DISPLAY, currentUserId); + expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, currentUserId); + + expectUserIsNotVisibleAtAll(previousCurrentUserId); + expectNoDisplayAssignedToUser(previousCurrentUserId); + + listener.verify(); + } + + @Test + public void testStartBgProfile_onDefaultDisplay_whenParentIsCurrentUser() throws Exception { + AsyncUserVisibilityListener listener = addListenerForEvents( + onInvisible(INITIAL_CURRENT_USER_ID), + onVisible(PARENT_USER_ID), + onVisible(PROFILE_USER_ID)); + startForegroundUser(PARENT_USER_ID); + + int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, + DEFAULT_DISPLAY); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); + + expectUserIsVisible(PROFILE_USER_ID); + expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY); + expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); + expectUserIsVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); + expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID); + + expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY); + expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID); + + listener.verify(); + } + + @Test public void testStartBgUser_onSecondaryDisplay() throws Exception { AsyncUserVisibilityListener listener = addListenerForNoEvents(); diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java index 6ceb38adf875..c2038311e740 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java @@ -37,6 +37,7 @@ import static org.junit.Assert.assertThrows; import android.annotation.UserIdInt; import android.os.Handler; +import android.text.TextUtils; import android.util.IntArray; import android.util.Log; @@ -135,66 +136,6 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { } @Test - public final void testStartFgUser_onDefaultDisplay() throws Exception { - AsyncUserVisibilityListener listener = addListenerForEvents( - onInvisible(INITIAL_CURRENT_USER_ID), - onVisible(USER_ID)); - - int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG, - DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); - - expectUserIsVisible(USER_ID); - expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY); - expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY); - // TODO(b/244644281): once isUserVisible() is fixed (see note there), this assertion will - // fail on MUMD, so we'll need to refactor / split this test (and possibly others) - expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID); - expectVisibleUsers(USER_ID); - - expectDisplayAssignedToUser(USER_ID, DEFAULT_DISPLAY); - expectUserAssignedToDisplay(DEFAULT_DISPLAY, USER_ID); - expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID); - expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID); - - expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY); - - listener.verify(); - } - - @Test - public final void testSwitchFgUser_onDefaultDisplay() throws Exception { - int previousCurrentUserId = OTHER_USER_ID; - int currentUserId = USER_ID; - AsyncUserVisibilityListener listener = addListenerForEvents( - onInvisible(INITIAL_CURRENT_USER_ID), - onVisible(previousCurrentUserId), - onInvisible(previousCurrentUserId), - onVisible(currentUserId)); - startForegroundUser(previousCurrentUserId); - - int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG, - DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); - - expectUserIsVisible(currentUserId); - expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY); - expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY); - expectUserIsVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID); - expectVisibleUsers(currentUserId); - - expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY); - expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId); - expectUserAssignedToDisplay(INVALID_DISPLAY, currentUserId); - expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, currentUserId); - - expectUserIsNotVisibleAtAll(previousCurrentUserId); - expectNoDisplayAssignedToUser(previousCurrentUserId); - - listener.verify(); - } - - @Test public final void testStartFgUser_onSecondaryDisplay() throws Exception { AsyncUserVisibilityListener listener = addListenerForNoEvents(); @@ -245,31 +186,6 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { } @Test - public final void testStartBgProfile_onDefaultDisplay_whenParentIsCurrentUser() - throws Exception { - AsyncUserVisibilityListener listener = addListenerForEvents( - onInvisible(INITIAL_CURRENT_USER_ID), - onVisible(PARENT_USER_ID), - onVisible(PROFILE_USER_ID)); - startForegroundUser(PARENT_USER_ID); - - int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, - DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); - - expectUserIsVisible(PROFILE_USER_ID); - expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY); - expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); - expectUserIsVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); - expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID); - - expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY); - expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID); - - listener.verify(); - } - - @Test public final void testStopVisibleProfile() throws Exception { AsyncUserVisibilityListener listener = addListenerForEvents( onInvisible(INITIAL_CURRENT_USER_ID), @@ -530,6 +446,14 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { .isFalse(); } + protected void expectUserIsNotVisibleOnDisplay(String when, @UserIdInt int userId, + int displayId) { + String suffix = TextUtils.isEmpty(when) ? "" : " on " + when; + expectWithMessage("mediator.isUserVisible(%s, %s)%s", userId, displayId, suffix) + .that(mMediator.isUserVisible(userId, displayId)) + .isFalse(); + } + protected void expectUserIsNotVisibleAtAll(@UserIdInt int userId) { expectWithMessage("mediator.isUserVisible(%s)", userId) .that(mMediator.isUserVisible(userId)) diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index fbd12936ed93..1c4309759186 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -54,7 +54,6 @@ android_test { "hamcrest-library", "servicestests-utils", "service-jobscheduler", - "service-permission.impl", // TODO: remove once Android migrates to JUnit 4.12, // which provides assertThrows "testng", diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceVolumeManagerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceVolumeManagerTest.java index 7acb6d66c834..7f54b63bfe4b 100644 --- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceVolumeManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceVolumeManagerTest.java @@ -84,12 +84,12 @@ public class AudioDeviceVolumeManagerTest { final AudioDeviceAttributes usbDevice = new AudioDeviceAttributes( /*native type*/ AudioSystem.DEVICE_OUT_USB_DEVICE, /*address*/ "bla"); - mAudioService.setDeviceVolume(volMin, usbDevice, mPackageName, TAG); + mAudioService.setDeviceVolume(volMin, usbDevice, mPackageName); mTestLooper.dispatchAll(); verify(mSpyAudioSystem, atLeast(1)).setStreamVolumeIndexAS( AudioManager.STREAM_MUSIC, minIndex, AudioSystem.DEVICE_OUT_USB_DEVICE); - mAudioService.setDeviceVolume(volMid, usbDevice, mPackageName, TAG); + mAudioService.setDeviceVolume(volMid, usbDevice, mPackageName); mTestLooper.dispatchAll(); verify(mSpyAudioSystem, atLeast(1)).setStreamVolumeIndexAS( AudioManager.STREAM_MUSIC, midIndex, AudioSystem.DEVICE_OUT_USB_DEVICE); diff --git a/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java index 60165588f578..cd2f205f5552 100644 --- a/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java @@ -29,7 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.backup.BackupAgent; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.IBackupManagerMonitor; import android.app.backup.IBackupObserver; import android.content.Context; @@ -148,18 +148,18 @@ public class UserBackupManagerServiceTest { } @Test - public void testGetOperationTypeFromTransport_returnsBackupByDefault() + public void testGetBackupDestinationFromTransport_returnsCloudByDefault() throws Exception { when(mTransportConnection.connectOrThrow(any())).thenReturn(mBackupTransport); when(mBackupTransport.getTransportFlags()).thenReturn(0); - int operationType = mService.getOperationTypeFromTransport(mTransportConnection); + int backupDestination = mService.getBackupDestinationFromTransport(mTransportConnection); - assertThat(operationType).isEqualTo(OperationType.BACKUP); + assertThat(backupDestination).isEqualTo(BackupDestination.CLOUD); } @Test - public void testGetOperationTypeFromTransport_returnsMigrationForMigrationTransport() + public void testGetBackupDestinationFromTransport_returnsDeviceTransferForD2dTransport() throws Exception { // This is a temporary flag to control the new behaviour until it's ready to be fully // rolled out. @@ -169,9 +169,9 @@ public class UserBackupManagerServiceTest { when(mBackupTransport.getTransportFlags()).thenReturn( BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER); - int operationType = mService.getOperationTypeFromTransport(mTransportConnection); + int backupDestination = mService.getBackupDestinationFromTransport(mTransportConnection); - assertThat(operationType).isEqualTo(OperationType.MIGRATION); + assertThat(backupDestination).isEqualTo(BackupDestination.DEVICE_TRANSFER); } @Test diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java index 310c8f4b5d69..48b0aada3969 100644 --- a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java @@ -23,7 +23,7 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; -import android.app.backup.BackupManager.OperationType; +import android.app.backup.BackupAnnotations.BackupDestination; import android.compat.testing.PlatformCompatChangeRule; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; @@ -78,7 +78,7 @@ public class BackupEligibilityRulesTest { MockitoAnnotations.initMocks(this); mUserId = UserHandle.USER_SYSTEM; - mBackupEligibilityRules = getBackupEligibilityRules(OperationType.BACKUP); + mBackupEligibilityRules = getBackupEligibilityRules(BackupDestination.CLOUD); } @Test @@ -225,7 +225,7 @@ public class BackupEligibilityRulesTest { /* flags */ 0, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( - OperationType.MIGRATION); + BackupDestination.DEVICE_TRANSFER); boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo); assertThat(isEligible).isTrue(); @@ -237,7 +237,7 @@ public class BackupEligibilityRulesTest { ApplicationInfo applicationInfo = getApplicationInfo(Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( - OperationType.MIGRATION); + BackupDestination.DEVICE_TRANSFER); boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo); assertThat(isEligible).isFalse(); @@ -250,7 +250,7 @@ public class BackupEligibilityRulesTest { ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID, /* flags */ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( - OperationType.ADB_BACKUP); + BackupDestination.ADB_BACKUP); when(mPackageManager.getPropertyAsUser(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP), eq(TEST_PACKAGE_NAME), isNull(), eq(mUserId))) .thenReturn(getAdbBackupProperty(/* allowAdbBackup */ false)); @@ -267,7 +267,7 @@ public class BackupEligibilityRulesTest { ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID, /* flags */ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( - OperationType.ADB_BACKUP); + BackupDestination.ADB_BACKUP); when(mPackageManager.getPropertyAsUser(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP), eq(TEST_PACKAGE_NAME), isNull(), eq(mUserId))) .thenReturn(getAdbBackupProperty(/* allowAdbBackup */ true)); @@ -284,7 +284,7 @@ public class BackupEligibilityRulesTest { ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID, /* flags */ ApplicationInfo.FLAG_DEBUGGABLE, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( - OperationType.ADB_BACKUP); + BackupDestination.ADB_BACKUP); boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo); @@ -298,7 +298,7 @@ public class BackupEligibilityRulesTest { ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID, ApplicationInfo.FLAG_ALLOW_BACKUP, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( - OperationType.ADB_BACKUP); + BackupDestination.ADB_BACKUP); boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo); @@ -312,7 +312,7 @@ public class BackupEligibilityRulesTest { ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID, /* flags */ 0, CUSTOM_BACKUP_AGENT_NAME); BackupEligibilityRules eligibilityRules = getBackupEligibilityRules( - OperationType.ADB_BACKUP); + BackupDestination.ADB_BACKUP); boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo); @@ -787,9 +787,10 @@ public class BackupEligibilityRulesTest { assertThat(result).isFalse(); } - private BackupEligibilityRules getBackupEligibilityRules(@OperationType int operationType) { + private BackupEligibilityRules getBackupEligibilityRules( + @BackupDestination int backupDestination) { return new BackupEligibilityRules(mPackageManager, mMockPackageManagerInternal, mUserId, - operationType); + backupDestination); } private static Signature generateSignature(byte i) { diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/OWNERS b/services/tests/servicestests/src/com/android/server/companion/virtual/OWNERS new file mode 100644 index 000000000000..29681045ac4a --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/OWNERS @@ -0,0 +1 @@ +include /services/companion/java/com/android/server/companion/virtual/OWNERS diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index 09dc367cceb4..0bd6f2c2d903 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -99,6 +99,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.function.Consumer; @Presubmit @@ -181,14 +182,36 @@ public class VirtualDeviceManagerServiceTest { return blockedActivities; } + private Intent createRestrictedActivityBlockedIntent(List displayCategories, + String targetDisplayCategory) { + mDeviceImpl.onVirtualDisplayCreatedLocked( + mDeviceImpl.createWindowPolicyController(displayCategories), DISPLAY_ID); + GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( + DISPLAY_ID); + doNothing().when(mContext).startActivityAsUser(any(), any(), any()); + + ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoveDevices= */ true, + targetDisplayCategory); + Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( + activityInfos.get(0), mAssociationInfo.getDisplayName()); + gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + return blockedAppIntent; + } + + private ArrayList<ActivityInfo> getActivityInfoList( - String packageName, String name, boolean displayOnRemoveDevices) { + String packageName, String name, boolean displayOnRemoveDevices, + String targetDisplayCategory) { ActivityInfo activityInfo = new ActivityInfo(); activityInfo.packageName = packageName; activityInfo.name = name; activityInfo.flags = displayOnRemoveDevices ? FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES : FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES; activityInfo.applicationInfo = mApplicationInfoMock; + activityInfo.targetDisplayCategory = targetDisplayCategory; return new ArrayList<>(Arrays.asList(activityInfo)); } @@ -298,7 +321,7 @@ public class VirtualDeviceManagerServiceTest { @Test public void onVirtualDisplayRemovedLocked_doesNotThrowException() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); // This call should not throw any exceptions. mDeviceImpl.onVirtualDisplayRemovedLocked(DISPLAY_ID); } @@ -317,7 +340,7 @@ public class VirtualDeviceManagerServiceTest { public void onVirtualDisplayRemovedLocked_listenersNotified() { mLocalService.registerVirtualDisplayListener(mDisplayListener); mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); mLocalService.onVirtualDisplayRemoved(mDeviceImpl, DISPLAY_ID); TestableLooper.get(this).processAllMessages(); @@ -379,7 +402,7 @@ public class VirtualDeviceManagerServiceTest { nullable(String.class), nullable(String.class), nullable(WorkSource.class), nullable(String.class), anyInt(), eq(null)); mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); verify(mIPowerManagerMock).acquireWakeLock(any(Binder.class), anyInt(), nullable(String.class), nullable(String.class), nullable(WorkSource.class), nullable(String.class), eq(DISPLAY_ID), eq(null)); @@ -388,9 +411,10 @@ public class VirtualDeviceManagerServiceTest { @Test public void onVirtualDisplayCreatedLocked_duplicateCalls_onlyOneWakeLockIsAcquired() throws RemoteException { - GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController(); + GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController( + new ArrayList<>()); mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); assertThrows(IllegalStateException.class, () -> mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID)); TestableLooper.get(this).processAllMessages(); @@ -409,7 +433,7 @@ public class VirtualDeviceManagerServiceTest { @Test public void onVirtualDisplayRemovedLocked_wakeLockIsReleased() throws RemoteException { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); ArgumentCaptor<IBinder> wakeLockCaptor = ArgumentCaptor.forClass(IBinder.class); TestableLooper.get(this).processAllMessages(); verify(mIPowerManagerMock).acquireWakeLock(wakeLockCaptor.capture(), @@ -425,7 +449,7 @@ public class VirtualDeviceManagerServiceTest { @Test public void addVirtualDisplay_displayNotReleased_wakeLockIsReleased() throws RemoteException { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); ArgumentCaptor<IBinder> wakeLockCaptor = ArgumentCaptor.forClass(IBinder.class); TestableLooper.get(this).processAllMessages(); verify(mIPowerManagerMock).acquireWakeLock(wakeLockCaptor.capture(), @@ -625,7 +649,7 @@ public class VirtualDeviceManagerServiceTest { @Test public void onAudioSessionStarting_hasVirtualAudioController() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); mDeviceImpl.onAudioSessionStarting(DISPLAY_ID, mRoutingCallback, mConfigChangedCallback); @@ -635,7 +659,7 @@ public class VirtualDeviceManagerServiceTest { @Test public void onAudioSessionEnded_noVirtualAudioController() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); mDeviceImpl.onAudioSessionStarting(DISPLAY_ID, mRoutingCallback, mConfigChangedCallback); mDeviceImpl.onAudioSessionEnded(); @@ -646,7 +670,7 @@ public class VirtualDeviceManagerServiceTest { @Test public void close_cleanVirtualAudioController() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); mDeviceImpl.onAudioSessionStarting(DISPLAY_ID, mRoutingCallback, mConfigChangedCallback); mDeviceImpl.close(); @@ -863,14 +887,16 @@ public class VirtualDeviceManagerServiceTest { @Test public void openNonBlockedAppOnVirtualDisplay_doesNotStartBlockedAlertActivity() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); ArrayList<ActivityInfo> activityInfos = getActivityInfoList( NONBLOCKED_APP_PACKAGE_NAME, - NONBLOCKED_APP_PACKAGE_NAME, /* displayOnRemoveDevices */ true); + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoveDevices */ true, + /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfos.get(0), mAssociationInfo.getDisplayName()); gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); @@ -882,14 +908,16 @@ public class VirtualDeviceManagerServiceTest { @Test public void openPermissionControllerOnVirtualDisplay_startBlockedAlertActivity() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); ArrayList<ActivityInfo> activityInfos = getActivityInfoList( PERMISSION_CONTROLLER_PACKAGE_NAME, - PERMISSION_CONTROLLER_PACKAGE_NAME, /* displayOnRemoveDevices */ false); + PERMISSION_CONTROLLER_PACKAGE_NAME, + /* displayOnRemoveDevices */ false, + /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfos.get(0), mAssociationInfo.getDisplayName()); gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); @@ -901,14 +929,16 @@ public class VirtualDeviceManagerServiceTest { @Test public void openSettingsOnVirtualDisplay_startBlockedAlertActivity() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); ArrayList<ActivityInfo> activityInfos = getActivityInfoList( SETTINGS_PACKAGE_NAME, - SETTINGS_PACKAGE_NAME, /* displayOnRemoveDevices */ true); + SETTINGS_PACKAGE_NAME, + /* displayOnRemoveDevices */ true, + /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfos.get(0), mAssociationInfo.getDisplayName()); gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); @@ -920,14 +950,16 @@ public class VirtualDeviceManagerServiceTest { @Test public void openVendingOnVirtualDisplay_startBlockedAlertActivity() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); ArrayList<ActivityInfo> activityInfos = getActivityInfoList( VENDING_PACKAGE_NAME, - VENDING_PACKAGE_NAME, /* displayOnRemoveDevices */ true); + VENDING_PACKAGE_NAME, + /* displayOnRemoveDevices */ true, + /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfos.get(0), mAssociationInfo.getDisplayName()); gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); @@ -939,14 +971,16 @@ public class VirtualDeviceManagerServiceTest { @Test public void openGoogleDialerOnVirtualDisplay_startBlockedAlertActivity() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); ArrayList<ActivityInfo> activityInfos = getActivityInfoList( GOOGLE_DIALER_PACKAGE_NAME, - GOOGLE_DIALER_PACKAGE_NAME, /* displayOnRemoveDevices */ true); + GOOGLE_DIALER_PACKAGE_NAME, + /* displayOnRemoveDevices */ true, + /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfos.get(0), mAssociationInfo.getDisplayName()); gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); @@ -958,14 +992,16 @@ public class VirtualDeviceManagerServiceTest { @Test public void openGoogleMapsOnVirtualDisplay_startBlockedAlertActivity() { mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); ArrayList<ActivityInfo> activityInfos = getActivityInfoList( GOOGLE_MAPS_PACKAGE_NAME, - GOOGLE_MAPS_PACKAGE_NAME, /* displayOnRemoveDevices */ true); + GOOGLE_MAPS_PACKAGE_NAME, + /* displayOnRemoveDevices */ true, + /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfos.get(0), mAssociationInfo.getDisplayName()); gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); @@ -978,7 +1014,7 @@ public class VirtualDeviceManagerServiceTest { public void registerRunningAppsChangedListener_onRunningAppsChanged_listenersNotified() { ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(UID_1, UID_2)); mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); @@ -993,7 +1029,7 @@ public class VirtualDeviceManagerServiceTest { public void noRunningAppsChangedListener_onRunningAppsChanged_doesNotThrowException() { ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(UID_1, UID_2)); mDeviceImpl.onVirtualDisplayCreatedLocked( - mDeviceImpl.createWindowPolicyController(), DISPLAY_ID); + mDeviceImpl.createWindowPolicyController(new ArrayList<>()), DISPLAY_ID); GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get( DISPLAY_ID); mDeviceImpl.onVirtualDisplayRemovedLocked(DISPLAY_ID); @@ -1003,4 +1039,37 @@ public class VirtualDeviceManagerServiceTest { assertThat(gwpc.getRunningAppsChangedListenersSizeForTesting()).isEqualTo(0); } + + @Test + public void nonRestrictedActivityOnRestrictedVirtualDisplay_startBlockedAlertActivity() { + Intent blockedAppIntent = createRestrictedActivityBlockedIntent(List.of("abc"), + /* targetDisplayCategory= */ null); + verify(mContext).startActivityAsUser(argThat(intent -> + intent.filterEquals(blockedAppIntent)), any(), any()); + + } + + @Test + public void restrictedActivityOnRestrictedVirtualDisplay_doesNotStartBlockedAlertActivity() { + Intent blockedAppIntent = createRestrictedActivityBlockedIntent(List.of("abc"), "abc"); + verify(mContext, never()).startActivityAsUser(argThat(intent -> + intent.filterEquals(blockedAppIntent)), any(), any()); + } + + @Test + public void restrictedActivityOnNonRestrictedVirtualDisplay_startBlockedAlertActivity() { + Intent blockedAppIntent = createRestrictedActivityBlockedIntent( + /* displayCategories= */ List.of(), "abc"); + verify(mContext).startActivityAsUser(argThat(intent -> + intent.filterEquals(blockedAppIntent)), any(), any()); + } + + @Test + public void + restrictedActivityOnNonMatchingRestrictedVirtualDisplay_startBlockedAlertActivity() { + Intent blockedAppIntent = createRestrictedActivityBlockedIntent(List.of("abc"), "def"); + verify(mContext).startActivityAsUser(argThat(intent -> + intent.filterEquals(blockedAppIntent)), any(), any()); + } + } diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java index 0262f564911b..3ca648cbcc30 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java @@ -72,22 +72,25 @@ public class VirtualAudioControllerTest { MockitoAnnotations.initMocks(this); mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); mVirtualAudioController = new VirtualAudioController(mContext); - mGenericWindowPolicyController = new GenericWindowPolicyController( - FLAG_SECURE, - SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, - /* allowedUsers= */ new ArraySet<>(), - /* allowedCrossTaskNavigations= */ new ArraySet<>(), - /* blockedCrossTaskNavigations= */ new ArraySet<>(), - /* allowedActivities= */ new ArraySet<>(), - /* blockedActivities= */ new ArraySet<>(), - VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED, - /* activityListener= */ null, - /* pipBlockedCallback= */ null, - /* activityBlockedCallback= */ null, - /* secureWindowCallback= */ null, - /* deviceProfile= */ DEVICE_PROFILE_APP_STREAMING); + mGenericWindowPolicyController = + new GenericWindowPolicyController( + FLAG_SECURE, + SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, + /* allowedUsers= */ new ArraySet<>(), + /* allowedCrossTaskNavigations= */ new ArraySet<>(), + /* blockedCrossTaskNavigations= */ new ArraySet<>(), + /* allowedActivities= */ new ArraySet<>(), + /* blockedActivities= */ new ArraySet<>(), + VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED, + /* activityListener= */ null, + /* pipBlockedCallback= */ null, + /* activityBlockedCallback= */ null, + /* secureWindowCallback= */ null, + /* deviceProfile= */ DEVICE_PROFILE_APP_STREAMING, + /* displayCategories= */ new ArrayList<>()); } + @Test public void startListening_receivesCallback() throws RemoteException { ArraySet<Integer> runningUids = new ArraySet<>(); diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java index 59c69d114884..ccc43f29b2d1 100644 --- a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java @@ -33,6 +33,7 @@ import com.android.server.display.brightness.strategy.DozeBrightnessStrategy; import com.android.server.display.brightness.strategy.InvalidBrightnessStrategy; import com.android.server.display.brightness.strategy.OverrideBrightnessStrategy; import com.android.server.display.brightness.strategy.ScreenOffBrightnessStrategy; +import com.android.server.display.brightness.strategy.TemporaryBrightnessStrategy; import org.junit.Before; import org.junit.Test; @@ -53,6 +54,8 @@ public final class DisplayBrightnessStrategySelectorTest { @Mock private OverrideBrightnessStrategy mOverrideBrightnessStrategy; @Mock + private TemporaryBrightnessStrategy mTemporaryBrightnessStrategy; + @Mock private InvalidBrightnessStrategy mInvalidBrightnessStrategy; @Mock private Context mContext; @@ -65,6 +68,7 @@ public final class DisplayBrightnessStrategySelectorTest { public void before() { MockitoAnnotations.initMocks(this); when(mContext.getResources()).thenReturn(mResources); + when(mInvalidBrightnessStrategy.getName()).thenReturn("InvalidBrightnessStrategy"); DisplayBrightnessStrategySelector.Injector injector = new DisplayBrightnessStrategySelector.Injector() { @Override @@ -83,6 +87,11 @@ public final class DisplayBrightnessStrategySelectorTest { } @Override + TemporaryBrightnessStrategy getTemporaryBrightnessStrategy() { + return mTemporaryBrightnessStrategy; + } + + @Override InvalidBrightnessStrategy getInvalidBrightnessStrategy() { return mInvalidBrightnessStrategy; } @@ -121,6 +130,16 @@ public final class DisplayBrightnessStrategySelectorTest { } @Test + public void selectStrategySelectsTemporaryStrategyWhenValid() { + DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock( + DisplayManagerInternal.DisplayPowerRequest.class); + displayPowerRequest.screenBrightnessOverride = Float.NaN; + when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(0.3f); + assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(displayPowerRequest, + Display.STATE_ON), mTemporaryBrightnessStrategy); + } + + @Test public void selectStrategySelectsInvalidStrategyWhenNoStrategyIsValid() { DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock( DisplayManagerInternal.DisplayPowerRequest.class); diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java new file mode 100644 index 000000000000..4a32796470c7 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display.brightness.strategy; + + +import static org.junit.Assert.assertEquals; + +import android.hardware.display.DisplayManagerInternal; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.display.DisplayBrightnessState; +import com.android.server.display.brightness.BrightnessReason; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) + +public class TemporaryBrightnessStrategyTest { + private TemporaryBrightnessStrategy mTemporaryBrightnessStrategy; + + @Before + public void before() { + mTemporaryBrightnessStrategy = new TemporaryBrightnessStrategy(); + } + + @Test + public void updateBrightnessWorksAsExpectedWhenTemporaryBrightnessIsSet() { + DisplayManagerInternal.DisplayPowerRequest + displayPowerRequest = new DisplayManagerInternal.DisplayPowerRequest(); + float temporaryBrightness = 0.2f; + mTemporaryBrightnessStrategy.setTemporaryScreenBrightness(temporaryBrightness); + BrightnessReason brightnessReason = new BrightnessReason(); + brightnessReason.setReason(BrightnessReason.REASON_TEMPORARY); + DisplayBrightnessState expectedDisplayBrightnessState = + new DisplayBrightnessState.Builder() + .setBrightness(temporaryBrightness) + .setBrightnessReason(brightnessReason) + .setSdrBrightness(temporaryBrightness) + .build(); + DisplayBrightnessState updatedDisplayBrightnessState = + mTemporaryBrightnessStrategy.updateBrightness(displayPowerRequest); + assertEquals(updatedDisplayBrightnessState, expectedDisplayBrightnessState); + assertEquals(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness(), + Float.NaN, 0.0f); + } + +} diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java index 5b114661fae8..09cd47a99cba 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java @@ -143,8 +143,12 @@ public class ArcTerminationActionFromAvrTest { Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_TV); assertThat(mNativeWrapper.getResultMessages()).contains(terminateArc); + mTestLooper.dispatchAll(); + + mTestLooper.moveTimeForward(ArcTerminationActionFromAvr.TIMEOUT_MS); + mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isTrue(); + assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse(); } @Test diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java index 7df007813b34..6a899e839ca8 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java @@ -102,7 +102,7 @@ public class DeviceSelectActionFromPlaybackTest { Collections.singletonList(HdmiDeviceInfo.DEVICE_PLAYBACK), new FakeAudioDeviceVolumeManagerWrapper()) { @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return true; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java index ac57834ed5b0..04197686e6a1 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java @@ -111,7 +111,7 @@ public class DeviceSelectActionFromTvTest { Collections.singletonList(HdmiDeviceInfo.DEVICE_TV), new FakeAudioDeviceVolumeManagerWrapper()) { @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return true; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java index 0028969d85a0..167e0f80ef28 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java @@ -80,6 +80,17 @@ final class FakeHdmiCecConfig extends HdmiCecConfig { R.bool.config_cecRoutingControlDisabled_default); doReturn(true).when(resources).getBoolean( + R.bool.config_cecSoundbarMode_userConfigurable); + doReturn(true).when(resources).getBoolean( + R.bool.config_cecSoundbarModeEnabled_allowed); + doReturn(false).when(resources).getBoolean( + R.bool.config_cecSoundbarModeEnabled_default); + doReturn(true).when(resources).getBoolean( + R.bool.config_cecSoundbarModeDisabled_allowed); + doReturn(true).when(resources).getBoolean( + R.bool.config_cecSoundbarModeDisabled_default); + + doReturn(true).when(resources).getBoolean( R.bool.config_cecPowerControlMode_userConfigurable); doReturn(true).when(resources).getBoolean( R.bool.config_cecPowerControlModeTv_allowed); @@ -348,6 +359,17 @@ final class FakeHdmiCecConfig extends HdmiCecConfig { doReturn(true).when(resources).getBoolean(R.bool.config_cecQuerySadMaxDisabled_allowed); doReturn(false).when(resources).getBoolean(R.bool.config_cecQuerySadMaxDisabled_default); + doReturn(true).when(resources).getBoolean( + R.bool.config_earcEnabled_userConfigurable); + doReturn(true).when(resources).getBoolean( + R.bool.config_earcFeatureEnabled_allowed); + doReturn(true).when(resources).getBoolean( + R.bool.config_earcFeatureEnabled_default); + doReturn(true).when(resources).getBoolean( + R.bool.config_earcFeatureDisabled_allowed); + doReturn(false).when(resources).getBoolean( + R.bool.config_earcFeatureDisabled_default); + return resources; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java index 8e756aea27a9..870b68165281 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java @@ -76,6 +76,7 @@ public final class HdmiCecConfigTest { .containsExactly(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.CEC_SETTING_NAME_ROUTING_CONTROL, + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, @@ -105,7 +106,8 @@ public final class HdmiCecConfigTest { HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_TRUEHD, HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DST, HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_WMAPRO, - HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX); + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX, + HdmiControlManager.SETTING_NAME_EARC_ENABLED); } @Test @@ -115,6 +117,7 @@ public final class HdmiCecConfigTest { .containsExactly(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.CEC_SETTING_NAME_ROUTING_CONTROL, + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, @@ -144,7 +147,8 @@ public final class HdmiCecConfigTest { HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_TRUEHD, HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DST, HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_WMAPRO, - HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX); + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX, + HdmiControlManager.SETTING_NAME_EARC_ENABLED); } @Test @@ -155,6 +159,7 @@ public final class HdmiCecConfigTest { .containsExactly(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, HdmiControlManager.CEC_SETTING_NAME_ROUTING_CONTROL, + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING, @@ -183,7 +188,8 @@ public final class HdmiCecConfigTest { HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_TRUEHD, HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DST, HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_WMAPRO, - HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX); + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX, + HdmiControlManager.SETTING_NAME_EARC_ENABLED); } @Test 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 08d0e9053e2b..7c6c990500f3 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java @@ -354,7 +354,7 @@ public class HdmiCecLocalDeviceAudioSystemTest { HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildSetSystemAudioMode( ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false); - assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage); + assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage); assertThat(mMusicMute).isTrue(); } 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 75c4d92ab9f9..3ed898366496 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -31,6 +31,7 @@ import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiPortInfo; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.tv.cec.V1_0.SendMessageResult; +import android.media.AudioManager; import android.os.Looper; import android.os.RemoteException; import android.os.test.TestLooper; @@ -45,6 +46,8 @@ import org.junit.Before; 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; import java.util.Collections; @@ -85,9 +88,13 @@ public class HdmiCecLocalDevicePlaybackTest { private boolean mActiveMediaSessionsPaused; private FakePowerManagerInternalWrapper mPowerManagerInternal = new FakePowerManagerInternalWrapper(); + @Mock + protected AudioManager mAudioManager; @Before public void setUp() { + MockitoAnnotations.initMocks(this); + Context context = InstrumentationRegistry.getTargetContext(); mMyLooper = mTestLooper.getLooper(); @@ -103,12 +110,17 @@ public class HdmiCecLocalDevicePlaybackTest { } @Override + AudioManager getAudioManager() { + return mAudioManager; + } + + @Override void pauseActiveMediaSessions() { mActiveMediaSessionsPaused = true; } @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return true; } @@ -1424,6 +1436,32 @@ public class HdmiCecLocalDevicePlaybackTest { } @Test + public void sendVolumeKeyEvent_toLocalDevice_discardMessage() { + HdmiCecLocalDeviceAudioSystem audioSystem = + new HdmiCecLocalDeviceAudioSystem(mHdmiControlService); + audioSystem.init(); + mLocalDevices.add(audioSystem); + mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); + mTestLooper.dispatchAll(); + + mHdmiControlService.setHdmiCecVolumeControlEnabledInternal( + HdmiControlManager.VOLUME_CONTROL_ENABLED); + mHdmiControlService.setSystemAudioActivated(true); + + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true); + mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false); + + HdmiCecMessage keyPressed = HdmiCecMessageBuilder.buildUserControlPressed( + mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP); + HdmiCecMessage keyReleased = HdmiCecMessageBuilder.buildUserControlReleased( + mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM); + mTestLooper.dispatchAll(); + + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyPressed); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyReleased); + } + + @Test public void handleSetStreamPath_broadcastsActiveSource() { HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, mPlaybackPhysicalAddress); 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 48e70fe4a60f..b30118cc969d 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java @@ -141,7 +141,7 @@ public class HdmiCecLocalDeviceTest { new HdmiControlService(context, Collections.emptyList(), new FakeAudioDeviceVolumeManagerWrapper()) { @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return isControlEnabled; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index 82c340145f8e..524610768554 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -136,7 +136,7 @@ public class HdmiCecLocalDeviceTvTest { super.wakeUp(); } @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return true; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java index a08e398b4010..4e5336e5748a 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java @@ -68,7 +68,7 @@ public class HdmiCecPowerStatusControllerTest { Collections.singletonList(HdmiDeviceInfo.DEVICE_PLAYBACK), new FakeAudioDeviceVolumeManagerWrapper()) { @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return true; } 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 8f6bee170b0e..ef2b21211297 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -44,6 +44,7 @@ import android.hardware.hdmi.HdmiPortInfo; import android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener; import android.hardware.hdmi.IHdmiControlStatusChangeListener; import android.hardware.hdmi.IHdmiVendorCommandListener; +import android.media.AudioManager; import android.os.Binder; import android.os.Looper; import android.os.RemoteException; @@ -58,7 +59,9 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Arrays; @@ -86,8 +89,12 @@ public class HdmiControlServiceTest { private HdmiPortInfo[] mHdmiPortInfo; private ArrayList<Integer> mLocalDeviceTypes = new ArrayList<>(); + @Mock protected AudioManager mAudioManager; + @Before public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy); @@ -132,6 +139,7 @@ public class HdmiControlServiceTest { mPowerManager = new FakePowerManagerWrapper(mContextSpy); mHdmiControlServiceSpy.setPowerManager(mPowerManager); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); + mHdmiControlServiceSpy.setAudioManager(mAudioManager); mTestLooper.dispatchAll(); } @@ -195,7 +203,7 @@ public class HdmiControlServiceTest { HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_1_4_B); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mNativeWrapper.clearResultMessages(); assertThat(mHdmiControlServiceSpy.getInitialPowerStatus()).isEqualTo( @@ -228,7 +236,7 @@ public class HdmiControlServiceTest { HdmiControlManager.HDMI_CEC_VERSION_2_0); mTestLooper.dispatchAll(); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mNativeWrapper.clearResultMessages(); mTestLooper.dispatchAll(); @@ -285,11 +293,11 @@ public class HdmiControlServiceTest { int volumeControlEnabled = HdmiControlManager.VOLUME_CONTROL_ENABLED; mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(volumeControlEnabled); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); assertThat(mHdmiControlServiceSpy.getHdmiCecVolumeControl()).isEqualTo( HdmiControlManager.VOLUME_CONTROL_DISABLED); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); assertThat(mHdmiControlServiceSpy.getHdmiCecVolumeControl()) .isEqualTo(volumeControlEnabled); } @@ -300,12 +308,12 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE, volumeControlEnabled); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue( HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo( volumeControlEnabled); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); assertThat(mHdmiControlServiceSpy.getHdmiCecConfig().getIntValue( HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE)).isEqualTo( volumeControlEnabled); @@ -320,13 +328,13 @@ public class HdmiControlServiceTest { VolumeControlFeatureCallback callback = new VolumeControlFeatureCallback(); mHdmiControlServiceSpy.addHdmiCecVolumeControlFeatureListener(callback); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); assertThat(callback.mCallbackReceived).isTrue(); assertThat(callback.mVolumeControlEnabled).isEqualTo( HdmiControlManager.VOLUME_CONTROL_DISABLED); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); assertThat(callback.mVolumeControlEnabled).isEqualTo( HdmiControlManager.VOLUME_CONTROL_ENABLED); } @@ -423,7 +431,7 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_1_4_B); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo( HdmiControlManager.HDMI_CEC_VERSION_1_4_B); } @@ -433,7 +441,7 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_2_0); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo( HdmiControlManager.HDMI_CEC_VERSION_2_0); } @@ -443,14 +451,14 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_1_4_B); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo( HdmiControlManager.HDMI_CEC_VERSION_1_4_B); mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_2_0); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); assertThat(mHdmiControlServiceSpy.getCecVersion()).isEqualTo( HdmiControlManager.HDMI_CEC_VERSION_2_0); } @@ -460,7 +468,7 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_1_4_B); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mTestLooper.dispatchAll(); mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildGiveFeatures(Constants.ADDR_TV, @@ -478,7 +486,7 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_2_0); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); @@ -500,7 +508,7 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_1_4_B); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); @@ -517,7 +525,7 @@ public class HdmiControlServiceTest { mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, HdmiControlManager.HDMI_CEC_VERSION_2_0); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); @@ -624,11 +632,11 @@ public class HdmiControlServiceTest { @Test public void initCec_statusListener_CecEnabled_CecAvailable_TvOn() { HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback(); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); mTestLooper.dispatchAll(); mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); @@ -647,11 +655,11 @@ public class HdmiControlServiceTest { @Test public void initCec_statusListener_CecEnabled_CecAvailable_TvStandby() { HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback(); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); mTestLooper.dispatchAll(); mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); @@ -670,11 +678,11 @@ public class HdmiControlServiceTest { @Test public void initCec_statusListener_CecEnabled_CecAvailable_TvTransientToOn() { HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback(); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); mTestLooper.dispatchAll(); mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); @@ -693,11 +701,11 @@ public class HdmiControlServiceTest { @Test public void initCec_statusListener_CecEnabled_CecAvailable_TvTransientToStandby() { HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback(); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); mTestLooper.dispatchAll(); mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback); - mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); @@ -1026,6 +1034,48 @@ public class HdmiControlServiceTest { .containsExactly(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM); } + @Test + public void setSoundbarMode_enabled_addAudioSystemLocalDevice() { + // Initialize the local devices excluding the audio system. + mHdmiControlServiceSpy.clearCecLocalDevices(); + mLocalDevices.remove(mAudioSystemDeviceSpy); + mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlServiceSpy.audioSystem()).isNull(); + + // Enable the setting and check if the audio system local device is found in the network. + mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, + HdmiControlManager.SOUNDBAR_MODE_ENABLED); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlServiceSpy.audioSystem()).isNotNull(); + } + + @Test + public void setSoundbarMode_disabled_removeAudioSystemLocalDevice() { + // Initialize the local devices excluding the audio system. + mHdmiControlServiceSpy.clearCecLocalDevices(); + mLocalDevices.remove(mAudioSystemDeviceSpy); + mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlServiceSpy.audioSystem()).isNull(); + + // Enable the setting and check if the audio system local device is found in the network. + mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, + HdmiControlManager.SOUNDBAR_MODE_ENABLED); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlServiceSpy.audioSystem()).isNotNull(); + + // Disable the setting and check if the audio system local device is removed from the + // network. + mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE, + HdmiControlManager.SOUNDBAR_MODE_DISABLED); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlServiceSpy.audioSystem()).isNull(); + } + protected static class MockPlaybackDevice extends HdmiCecLocalDevicePlayback { private boolean mCanGoToStandby; diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java index c07d4be78047..f719ca16357c 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java @@ -99,7 +99,7 @@ public class RequestSadActionTest { new HdmiControlService(context, Collections.singletonList(HdmiDeviceInfo.DEVICE_TV), new FakeAudioDeviceVolumeManagerWrapper()) { @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return true; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java index f5bf30b1ec1e..be62df8517b4 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java @@ -151,7 +151,7 @@ public class RoutingControlActionTest { Collections.singletonList(HdmiDeviceInfo.DEVICE_TV), new FakeAudioDeviceVolumeManagerWrapper()) { @Override - boolean isControlEnabled() { + boolean isCecControlEnabled() { return true; } diff --git a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt index 6590a2b500e4..ecd9d893330a 100644 --- a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt +++ b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt @@ -16,6 +16,7 @@ package com.android.server.input +import android.bluetooth.BluetoothDevice import android.content.Context import android.content.ContextWrapper import android.hardware.BatteryState.STATUS_CHARGING @@ -33,6 +34,8 @@ import android.os.test.TestLooper import android.platform.test.annotations.Presubmit import android.view.InputDevice import androidx.test.InstrumentationRegistry +import com.android.server.input.BatteryController.BluetoothBatteryManager +import com.android.server.input.BatteryController.BluetoothBatteryManager.BluetoothBatteryListener import com.android.server.input.BatteryController.POLLING_PERIOD_MILLIS import com.android.server.input.BatteryController.UEventManager import com.android.server.input.BatteryController.UEventManager.UEventBatteryListener @@ -52,6 +55,7 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.notNull import org.mockito.Mock import org.mockito.Mockito.anyInt @@ -172,6 +176,8 @@ class BatteryControllerTests { const val SECOND_DEVICE_ID = 11 const val USI_DEVICE_ID = 101 const val SECOND_USI_DEVICE_ID = 102 + const val BT_DEVICE_ID = 100001 + const val SECOND_BT_DEVICE_ID = 100002 const val TIMESTAMP = 123456789L } @@ -184,6 +190,8 @@ class BatteryControllerTests { private lateinit var iInputManager: IInputManager @Mock private lateinit var uEventManager: UEventManager + @Mock + private lateinit var bluetoothBatteryManager: BluetoothBatteryManager private lateinit var batteryController: BatteryController private lateinit var context: Context @@ -203,11 +211,13 @@ class BatteryControllerTests { addInputDevice(DEVICE_ID) addInputDevice(SECOND_DEVICE_ID) - batteryController = BatteryController(context, native, testLooper.looper, uEventManager) + batteryController = BatteryController(context, native, testLooper.looper, uEventManager, + bluetoothBatteryManager) batteryController.systemRunning() val listenerCaptor = ArgumentCaptor.forClass(IInputDevicesChangedListener::class.java) verify(iInputManager).registerInputDevicesChangedListener(listenerCaptor.capture()) devicesChangedListener = listenerCaptor.value + testLooper.dispatchAll() } private fun notifyDeviceChanged( @@ -230,7 +240,7 @@ class BatteryControllerTests { private fun addInputDevice( deviceId: Int, hasBattery: Boolean = true, - supportsUsi: Boolean = false + supportsUsi: Boolean = false, ) { deviceGenerationMap[deviceId] = 0 notifyDeviceChanged(deviceId, hasBattery, supportsUsi) @@ -634,4 +644,125 @@ class BatteryControllerTests { assertThat("battery state matches", batteryController.getBatteryState(USI_DEVICE_ID), matchesState(USI_DEVICE_ID, status = STATUS_UNKNOWN, capacity = 0f)) } + + @Test + fun testRegisterBluetoothListenerForMonitoredBluetoothDevices() { + `when`(iInputManager.getInputDeviceBluetoothAddress(BT_DEVICE_ID)) + .thenReturn("AA:BB:CC:DD:EE:FF") + `when`(iInputManager.getInputDeviceBluetoothAddress(SECOND_BT_DEVICE_ID)) + .thenReturn("11:22:33:44:55:66") + addInputDevice(BT_DEVICE_ID) + testLooper.dispatchNext() + addInputDevice(SECOND_BT_DEVICE_ID) + testLooper.dispatchNext() + + // Ensure that a BT battery listener is not added when there are no monitored BT devices. + verify(bluetoothBatteryManager, never()).addListener(any()) + + val bluetoothListener = ArgumentCaptor.forClass(BluetoothBatteryListener::class.java) + val listener = createMockListener() + + // The BT battery listener is added when the first BT input device is monitored. + batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID) + verify(bluetoothBatteryManager).addListener(bluetoothListener.capture()) + + // The BT listener is only added once for all BT devices. + batteryController.registerBatteryListener(SECOND_BT_DEVICE_ID, listener, PID) + verify(bluetoothBatteryManager, times(1)).addListener(any()) + + // The BT listener is only removed when there are no monitored BT devices. + batteryController.unregisterBatteryListener(BT_DEVICE_ID, listener, PID) + verify(bluetoothBatteryManager, never()).removeListener(any()) + + `when`(iInputManager.getInputDeviceBluetoothAddress(SECOND_BT_DEVICE_ID)) + .thenReturn(null) + notifyDeviceChanged(SECOND_BT_DEVICE_ID) + testLooper.dispatchNext() + verify(bluetoothBatteryManager).removeListener(bluetoothListener.value) + } + + @Test + fun testNotifiesBluetoothBatteryChanges() { + `when`(iInputManager.getInputDeviceBluetoothAddress(BT_DEVICE_ID)) + .thenReturn("AA:BB:CC:DD:EE:FF") + `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(21) + addInputDevice(BT_DEVICE_ID) + val bluetoothListener = ArgumentCaptor.forClass(BluetoothBatteryListener::class.java) + val listener = createMockListener() + batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID) + verify(bluetoothBatteryManager).addListener(bluetoothListener.capture()) + listener.verifyNotified(BT_DEVICE_ID, capacity = 0.21f) + + // When the state has not changed, the listener is not notified again. + bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF") + listener.verifyNotified(BT_DEVICE_ID, mode = times(1), capacity = 0.21f) + + `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(25) + bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF") + listener.verifyNotified(BT_DEVICE_ID, capacity = 0.25f) + } + + @Test + fun testBluetoothBatteryIsPrioritized() { + `when`(native.getBatteryDevicePath(BT_DEVICE_ID)).thenReturn("/sys/dev/bt_device") + `when`(iInputManager.getInputDeviceBluetoothAddress(BT_DEVICE_ID)) + .thenReturn("AA:BB:CC:DD:EE:FF") + `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(21) + `when`(native.getBatteryCapacity(BT_DEVICE_ID)).thenReturn(98) + addInputDevice(BT_DEVICE_ID) + val bluetoothListener = ArgumentCaptor.forClass(BluetoothBatteryListener::class.java) + val listener = createMockListener() + val uEventListener = ArgumentCaptor.forClass(UEventBatteryListener::class.java) + + // When the device is first monitored and both native and BT battery is available, + // the latter is used. + batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID) + verify(bluetoothBatteryManager).addListener(bluetoothListener.capture()) + verify(uEventManager).addListener(uEventListener.capture(), any()) + listener.verifyNotified(BT_DEVICE_ID, capacity = 0.21f) + assertThat("battery state matches", batteryController.getBatteryState(BT_DEVICE_ID), + matchesState(BT_DEVICE_ID, capacity = 0.21f)) + + // If only the native battery state changes the listener is not notified. + `when`(native.getBatteryCapacity(BT_DEVICE_ID)).thenReturn(97) + uEventListener.value!!.onBatteryUEvent(TIMESTAMP) + listener.verifyNotified(BT_DEVICE_ID, mode = times(1), capacity = 0.21f) + assertThat("battery state matches", batteryController.getBatteryState(BT_DEVICE_ID), + matchesState(BT_DEVICE_ID, capacity = 0.21f)) + } + + @Test + fun testFallBackToNativeBatteryStateWhenBluetoothStateInvalid() { + `when`(native.getBatteryDevicePath(BT_DEVICE_ID)).thenReturn("/sys/dev/bt_device") + `when`(iInputManager.getInputDeviceBluetoothAddress(BT_DEVICE_ID)) + .thenReturn("AA:BB:CC:DD:EE:FF") + `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(21) + `when`(native.getBatteryCapacity(BT_DEVICE_ID)).thenReturn(98) + addInputDevice(BT_DEVICE_ID) + val bluetoothListener = ArgumentCaptor.forClass(BluetoothBatteryListener::class.java) + val listener = createMockListener() + val uEventListener = ArgumentCaptor.forClass(UEventBatteryListener::class.java) + + batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID) + verify(bluetoothBatteryManager).addListener(bluetoothListener.capture()) + verify(uEventManager).addListener(uEventListener.capture(), any()) + listener.verifyNotified(BT_DEVICE_ID, capacity = 0.21f) + + // Fall back to the native state when BT is off. + `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))) + .thenReturn(BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF) + bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF") + listener.verifyNotified(BT_DEVICE_ID, capacity = 0.98f) + + `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(22) + bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF") + verify(bluetoothBatteryManager).addListener(bluetoothListener.capture()) + listener.verifyNotified(BT_DEVICE_ID, capacity = 0.22f) + + // Fall back to the native state when BT battery is unknown. + `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))) + .thenReturn(BluetoothDevice.BATTERY_LEVEL_UNKNOWN) + bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF") + listener.verifyNotified(BT_DEVICE_ID, mode = times(2), capacity = 0.98f) + } } diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java index 153d746aa8ec..0d6bb8a1aa50 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java @@ -24,6 +24,7 @@ import static android.app.time.Capabilities.CAPABILITY_POSSESSED; import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_GEO; import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_MANUAL; import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_TELEPHONY; +import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_UNKNOWN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -51,11 +52,11 @@ public class ConfigurationInternalTest { /** * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection - * is supported (and geo detection is supported) + * is supported (both telephony and geo detection are supported) */ @Test @Parameters({ "true,true", "true,false", "false,true", "false,false" }) - public void test_autoDetectionSupported_capabilitiesAndConfiguration( + public void test_telephonyAndGeoSupported_capabilitiesAndConfiguration( boolean userConfigAllowed, boolean bypassUserPolicyChecks) { ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() .setUserId(ARBITRARY_USER_ID) @@ -72,18 +73,20 @@ public class ConfigurationInternalTest { boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks); - // Auto-detection enabled. + // Auto-detection enabled, location enabled. { - ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) .build(); - assertTrue(autoOnConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getGeoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior()); - assertTrue(autoOnConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_GEO, autoOnConfig.getDetectionMode()); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertTrue(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_GEO, config.getDetectionMode()); - TimeZoneCapabilities capabilities = autoOnConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); @@ -99,24 +102,58 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOnConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertTrue(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection enabled, location disabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(false) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertFalse(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_TELEPHONY, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getSetManualTimeZoneCapability()); + } + // This has user privacy implications so it is not restricted in the same way as others. + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); assertTrue(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } // Auto-detection disabled. { - ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(false) .build(); - assertFalse(autoOffConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOffConfig.getGeoDetectionEnabledSetting()); - assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior()); - assertFalse(autoOffConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode()); + assertFalse(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); - TimeZoneCapabilities capabilities = - autoOffConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); @@ -132,7 +169,7 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_NOT_APPLICABLE, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOffConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); assertFalse(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } @@ -161,18 +198,49 @@ public class ConfigurationInternalTest { boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks); - // Auto-detection enabled. + // Auto-detection enabled, location enabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability()); + } + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertTrue(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection enabled, location disabled. { - ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(false) .build(); - assertTrue(autoOnConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getGeoDetectionEnabledSetting()); - assertFalse(autoOnConfig.getAutoDetectionEnabledBehavior()); - assertFalse(autoOnConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_MANUAL, autoOnConfig.getDetectionMode()); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertFalse(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); - TimeZoneCapabilities capabilities = autoOnConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabledCapability()); if (userRestrictionsExpected) { @@ -183,7 +251,7 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOnConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); assertTrue(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } @@ -219,11 +287,11 @@ public class ConfigurationInternalTest { /** * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection - * is supported (and geo detection is not supported). + * is supported (telephony only). */ @Test @Parameters({ "true,true", "true,false", "false,true", "false,false" }) - public void test_geoDetectNotSupported_capabilitiesAndConfiguration( + public void test_onlyTelephonySupported_capabilitiesAndConfiguration( boolean userConfigAllowed, boolean bypassUserPolicyChecks) { ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() .setUserId(ARBITRARY_USER_ID) @@ -242,16 +310,16 @@ public class ConfigurationInternalTest { // Auto-detection enabled. { - ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(true) .build(); - assertTrue(autoOnConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getGeoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior()); - assertFalse(autoOnConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_TELEPHONY, autoOnConfig.getDetectionMode()); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_TELEPHONY, config.getDetectionMode()); - TimeZoneCapabilities capabilities = autoOnConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); @@ -266,18 +334,139 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOnConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); assertTrue(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } // Auto-detection disabled. { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(false) + .build(); + assertFalse(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability()); + } + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertFalse(configuration.isAutoDetectionEnabled()); + assertTrue(configuration.isGeoDetectionEnabled()); + } + } + + /** + * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection + * is supported (only geo detection) + */ + @Test + @Parameters({ "true,true", "true,false", "false,true", "false,false" }) + public void test_onlyGeoSupported_capabilitiesAndConfiguration( + boolean userConfigAllowed, boolean bypassUserPolicyChecks) { + ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() + .setUserId(ARBITRARY_USER_ID) + .setUserConfigAllowed(userConfigAllowed) + .setTelephonyDetectionFeatureSupported(false) + .setGeoDetectionFeatureSupported(true) + .setGeoDetectionRunInBackgroundEnabled(false) + .setTelephonyFallbackSupported(false) + .setEnhancedMetricsCollectionEnabled(false) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) + .setGeoDetectionEnabledSetting(false) + .build(); + + boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks); + + // Auto-detection enabled, location enabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertFalse(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertTrue(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_GEO, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getSetManualTimeZoneCapability()); + } + // This capability is always "not supported" if geo detection is the only mechanism. + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertFalse(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection enabled, location disabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(false) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertFalse(config.getLocationEnabledSetting()); + assertFalse(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_UNKNOWN, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getSetManualTimeZoneCapability()); + } + // This capability is always "not supported" if geo detection is the only mechanism. + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertFalse(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection disabled. + { ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(false) .build(); assertFalse(autoOffConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOffConfig.getGeoDetectionEnabledSetting()); + assertFalse(autoOffConfig.getGeoDetectionEnabledSetting()); assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior()); assertFalse(autoOffConfig.isGeoDetectionExecutionEnabled()); assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode()); @@ -287,18 +476,21 @@ public class ConfigurationInternalTest { if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); - assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); } else { assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabledCapability()); - assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability()); + assertEquals(CAPABILITY_POSSESSED, + capabilities.getSetManualTimeZoneCapability()); } + // This capability is always "not supported" if geo detection is the only mechanism. assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabledCapability()); TimeZoneConfiguration configuration = autoOffConfig.asConfiguration(); assertFalse(configuration.isAutoDetectionEnabled()); - assertTrue(configuration.isGeoDetectionEnabled()); + assertFalse(configuration.isGeoDetectionEnabled()); } } @@ -317,7 +509,10 @@ public class ConfigurationInternalTest { assertTrue(config.isTelephonyFallbackSupported()); } - /** Tests when {@link ConfigurationInternal#getGeoDetectionRunInBackgroundEnabled()} is true. */ + /** + * Tests when {@link ConfigurationInternal#getGeoDetectionRunInBackgroundEnabledSetting()} + * is true. + */ @Test public void test_geoDetectionRunInBackgroundEnabled() { ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java index ea801e887c4c..8207c1915edb 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java @@ -158,7 +158,7 @@ public class MetricsTimeZoneDetectorStateTest { metricsTimeZoneDetectorState.isGeoDetectionSupported()); assertEquals(configurationInternal.isTelephonyFallbackSupported(), metricsTimeZoneDetectorState.isTelephonyTimeZoneFallbackSupported()); - assertEquals(configurationInternal.getGeoDetectionRunInBackgroundEnabled(), + assertEquals(configurationInternal.getGeoDetectionRunInBackgroundEnabledSetting(), metricsTimeZoneDetectorState.getGeoDetectionRunInBackgroundEnabled()); assertEquals(configurationInternal.isEnhancedMetricsCollectionEnabled(), metricsTimeZoneDetectorState.isEnhancedMetricsCollectionEnabled()); diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java index b991c5a30415..74efdb5d6d98 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java @@ -880,7 +880,7 @@ public class TimeZoneDetectorStrategyImplTest { TimeZoneDetectorStatus expectedInitialDetectorStatus = new TimeZoneDetectorStatus( DETECTOR_STATUS_RUNNING, TELEPHONY_ALGORITHM_RUNNING_STATUS, - LocationTimeZoneAlgorithmStatus.UNKNOWN); + LocationTimeZoneAlgorithmStatus.RUNNING_NOT_REPORTED); script.verifyCachedDetectorStatus(expectedInitialDetectorStatus); LocationTimeZoneAlgorithmStatus algorithmStatus1 = new LocationTimeZoneAlgorithmStatus( 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 afec08505257..d54d1fed1016 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1101,10 +1101,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { new NotificationChannel("id", "name", IMPORTANCE_HIGH); mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel); - // pretend only this following part is called by the app (system permissions are required to - // update the notification channel on behalf of the user above) - mService.isSystemUid = false; - // Recreating with a lower importance leaves channel unchanged. final NotificationChannel dupeChannel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW); @@ -1130,46 +1126,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testCreateNotificationChannels_fromAppCannotSetFields() throws Exception { - // Confirm that when createNotificationChannels is called from the relevant app and not - // system, then it cannot set fields that can't be set by apps - mService.isSystemUid = false; - - final NotificationChannel channel = - new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); - channel.setBypassDnd(true); - channel.setAllowBubbles(true); - - mBinderService.createNotificationChannels(PKG, - new ParceledListSlice(Arrays.asList(channel))); - - final NotificationChannel createdChannel = - mBinderService.getNotificationChannel(PKG, mContext.getUserId(), PKG, "id"); - assertFalse(createdChannel.canBypassDnd()); - assertFalse(createdChannel.canBubble()); - } - - @Test - public void testCreateNotificationChannels_fromSystemCanSetFields() throws Exception { - // Confirm that when createNotificationChannels is called from system, - // then it can set fields that can't be set by apps - mService.isSystemUid = true; - - final NotificationChannel channel = - new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); - channel.setBypassDnd(true); - channel.setAllowBubbles(true); - - mBinderService.createNotificationChannels(PKG, - new ParceledListSlice(Arrays.asList(channel))); - - final NotificationChannel createdChannel = - mBinderService.getNotificationChannel(PKG, mContext.getUserId(), PKG, "id"); - assertTrue(createdChannel.canBypassDnd()); - assertTrue(createdChannel.canBubble()); - } - - @Test public void testBlockedNotifications_suspended() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true); @@ -3132,8 +3088,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testDeleteChannelGroupChecksForFgses() throws Exception { - // the setup for this test requires it to seem like it's coming from the app - mService.isSystemUid = false; when(mCompanionMgr.getAssociations(PKG, UserHandle.getUserId(mUid))) .thenReturn(singletonList(mock(AssociationInfo.class))); CountDownLatch latch = new CountDownLatch(2); @@ -3146,7 +3100,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ParceledListSlice<NotificationChannel> pls = new ParceledListSlice(ImmutableList.of(notificationChannel)); try { - mBinderService.createNotificationChannels(PKG, pls); + mBinderService.createNotificationChannelsForPackage(PKG, mUid, pls); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -3165,10 +3119,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ParceledListSlice<NotificationChannel> pls = new ParceledListSlice(ImmutableList.of(notificationChannel)); try { - // Because existing channels won't have their groups overwritten when the call - // is from the app, this call won't take the channel out of the group - mBinderService.createNotificationChannels(PKG, pls); - mBinderService.deleteNotificationChannelGroup(PKG, "group"); + mBinderService.createNotificationChannelsForPackage(PKG, mUid, pls); + mBinderService.deleteNotificationChannelGroup(PKG, "group"); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -8729,7 +8681,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals("friend", friendChannel.getConversationId()); assertEquals(null, original.getConversationId()); assertEquals(original.canShowBadge(), friendChannel.canShowBadge()); - assertEquals(original.canBubble(), friendChannel.canBubble()); // called by system + assertFalse(friendChannel.canBubble()); // can't be modified by app assertFalse(original.getId().equals(friendChannel.getId())); assertNotNull(friendChannel.getId()); } diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java index f848c4013fa9..a9cdf7e5bc08 100644 --- a/telephony/common/com/android/internal/telephony/SmsApplication.java +++ b/telephony/common/com/android/internal/telephony/SmsApplication.java @@ -210,6 +210,15 @@ public final class SmsApplication { } /** + * Returns the userHandle of the current process, if called from a system app, + * otherwise it returns the caller's userHandle + * @return userHandle of the caller. + */ + private static UserHandle getIncomingUserHandle() { + return UserHandle.of(getIncomingUserId()); + } + + /** * Returns the list of available SMS apps defined as apps that are registered for both the * SMS_RECEIVED_ACTION (SMS) and WAP_PUSH_RECEIVED_ACTION (MMS) broadcasts (and their broadcast * receivers are enabled) @@ -951,24 +960,28 @@ public final class SmsApplication { */ @UnsupportedAppUsage public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) { - return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId()); + return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle()); } /** * Gets the default SMS application on a given user * @param context context from the calling app * @param updateIfNeeded update the default app if there is no valid default app configured. - * @param userId target user ID. + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. * @return component name of the app and class to deliver SMS messages to */ - @VisibleForTesting public static ComponentName getDefaultSmsApplicationAsUser(Context context, - boolean updateIfNeeded, int userId) { + boolean updateIfNeeded, @Nullable UserHandle userHandle) { + if (userHandle == null) { + userHandle = getIncomingUserHandle(); + } + final long token = Binder.clearCallingIdentity(); try { ComponentName component = null; SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); + userHandle.getIdentifier()); if (smsApplicationData != null) { component = new ComponentName(smsApplicationData.mPackageName, smsApplicationData.mSmsReceiverClass); @@ -987,23 +1000,28 @@ public final class SmsApplication { */ @UnsupportedAppUsage public static ComponentName getDefaultMmsApplication(Context context, boolean updateIfNeeded) { - return getDefaultMmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId()); + return getDefaultMmsApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle()); } /** * Gets the default MMS application on a given user * @param context context from the calling app * @param updateIfNeeded update the default app if there is no valid default app configured. - * @param userId target user ID. + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. * @return component name of the app and class to deliver MMS messages to. */ public static ComponentName getDefaultMmsApplicationAsUser(Context context, - boolean updateIfNeeded, int userId) { + boolean updateIfNeeded, @Nullable UserHandle userHandle) { + if (userHandle == null) { + userHandle = getIncomingUserHandle(); + } + final long token = Binder.clearCallingIdentity(); try { ComponentName component = null; SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); + userHandle.getIdentifier()); if (smsApplicationData != null) { component = new ComponentName(smsApplicationData.mPackageName, smsApplicationData.mMmsReceiverClass); @@ -1024,23 +1042,28 @@ public final class SmsApplication { public static ComponentName getDefaultRespondViaMessageApplication(Context context, boolean updateIfNeeded) { return getDefaultRespondViaMessageApplicationAsUser(context, updateIfNeeded, - getIncomingUserId()); + getIncomingUserHandle()); } /** * Gets the default Respond Via Message application on a given user * @param context context from the calling app * @param updateIfNeeded update the default app if there is no valid default app configured - * @param userId target user ID. + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. * @return component name of the app and class to direct Respond Via Message intent to */ public static ComponentName getDefaultRespondViaMessageApplicationAsUser(Context context, - boolean updateIfNeeded, int userId) { + boolean updateIfNeeded, @Nullable UserHandle userHandle) { + if (userHandle == null) { + userHandle = getIncomingUserHandle(); + } + final long token = Binder.clearCallingIdentity(); try { ComponentName component = null; SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); + userHandle.getIdentifier()); if (smsApplicationData != null) { component = new ComponentName(smsApplicationData.mPackageName, smsApplicationData.mRespondViaMessageClass); @@ -1062,6 +1085,7 @@ public final class SmsApplication { public static ComponentName getDefaultSendToApplication(Context context, boolean updateIfNeeded) { int userId = getIncomingUserId(); + final long token = Binder.clearCallingIdentity(); try { ComponentName component = null; @@ -1087,7 +1111,7 @@ public final class SmsApplication { public static ComponentName getDefaultExternalTelephonyProviderChangedApplication( Context context, boolean updateIfNeeded) { return getDefaultExternalTelephonyProviderChangedApplicationAsUser(context, updateIfNeeded, - getIncomingUserId()); + getIncomingUserHandle()); } /** @@ -1095,16 +1119,21 @@ public final class SmsApplication { * MmsProvider on a given user. * @param context context from the calling app * @param updateIfNeeded update the default app if there is no valid default app configured - * @param userId target user ID. + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. * @return component name of the app and class to deliver change intents to. */ public static ComponentName getDefaultExternalTelephonyProviderChangedApplicationAsUser( - Context context, boolean updateIfNeeded, int userId) { + Context context, boolean updateIfNeeded, @Nullable UserHandle userHandle) { + if (userHandle == null) { + userHandle = getIncomingUserHandle(); + } + final long token = Binder.clearCallingIdentity(); try { ComponentName component = null; SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); + userHandle.getIdentifier()); if (smsApplicationData != null && smsApplicationData.mProviderChangedReceiverClass != null) { component = new ComponentName(smsApplicationData.mPackageName, @@ -1124,23 +1153,28 @@ public final class SmsApplication { */ public static ComponentName getDefaultSimFullApplication( Context context, boolean updateIfNeeded) { - return getDefaultSimFullApplicationAsUser(context, updateIfNeeded, getIncomingUserId()); + return getDefaultSimFullApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle()); } /** * Gets the default application that handles sim full event on a given user. * @param context context from the calling app * @param updateIfNeeded update the default app if there is no valid default app configured - * @param userId target user ID. + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. * @return component name of the app and class to deliver change intents to */ public static ComponentName getDefaultSimFullApplicationAsUser(Context context, - boolean updateIfNeeded, int userId) { + boolean updateIfNeeded, @Nullable UserHandle userHandle) { + if (userHandle == null) { + userHandle = getIncomingUserHandle(); + } + final long token = Binder.clearCallingIdentity(); try { ComponentName component = null; SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); + userHandle.getIdentifier()); if (smsApplicationData != null && smsApplicationData.mSimFullReceiverClass != null) { component = new ComponentName(smsApplicationData.mPackageName, @@ -1153,19 +1187,35 @@ public final class SmsApplication { } /** - * Returns whether need to wrgetIncomingUserIdite the SMS message to SMS database for this - * package. + * Returns whether it is required to write the SMS message to SMS database for this package. + * + * @param packageName the name of the package to be checked + * @param context context from the calling app + * @return true if it is required to write SMS message to SMS database for this package. + * * <p> * Caller must pass in the correct user context if calling from a singleton service. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean shouldWriteMessageForPackage(String packageName, Context context) { - return !shouldWriteMessageForPackageAsUser(packageName, context, getIncomingUserId()); + return !shouldWriteMessageForPackageAsUser(packageName, context, getIncomingUserHandle()); } + /** + * Returns whether it is required to write the SMS message to SMS database for this package. + * + * @param packageName the name of the package to be checked + * @param context context from the calling app + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. + * @return true if it is required to write SMS message to SMS database for this package. + * + * <p> + * Caller must pass in the correct user context if calling from a singleton service. + */ public static boolean shouldWriteMessageForPackageAsUser(String packageName, Context context, - int userId) { - return !isDefaultSmsApplicationAsUser(context, packageName, userId); + @Nullable UserHandle userHandle) { + return !isDefaultSmsApplicationAsUser(context, packageName, userHandle); } /** @@ -1177,7 +1227,7 @@ public final class SmsApplication { */ @UnsupportedAppUsage public static boolean isDefaultSmsApplication(Context context, String packageName) { - return isDefaultSmsApplicationAsUser(context, packageName, getIncomingUserId()); + return isDefaultSmsApplicationAsUser(context, packageName, getIncomingUserHandle()); } /** @@ -1185,16 +1235,22 @@ public final class SmsApplication { * * @param context context from the calling app * @param packageName the name of the package to be checked - * @param userId target user ID. + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. * @return true if the package is default sms app or bluetooth */ public static boolean isDefaultSmsApplicationAsUser(Context context, String packageName, - int userId) { + @Nullable UserHandle userHandle) { if (packageName == null) { return false; } + + if (userHandle == null) { + userHandle = getIncomingUserHandle(); + } + ComponentName component = getDefaultSmsApplicationAsUser(context, false, - userId); + userHandle); if (component == null) { return false; } @@ -1222,7 +1278,7 @@ public final class SmsApplication { */ @UnsupportedAppUsage public static boolean isDefaultMmsApplication(Context context, String packageName) { - return isDefaultMmsApplicationAsUser(context, packageName, getIncomingUserId()); + return isDefaultMmsApplicationAsUser(context, packageName, getIncomingUserHandle()); } /** @@ -1230,17 +1286,22 @@ public final class SmsApplication { * * @param context context from the calling app * @param packageName the name of the package to be checked - * @param userId target user ID. + * @param userHandle target user handle + * if {@code null} is passed in then calling package uid is used to find out target user handle. * @return true if the package is default mms app or bluetooth */ public static boolean isDefaultMmsApplicationAsUser(Context context, String packageName, - int userId) { + @Nullable UserHandle userHandle) { if (packageName == null) { return false; } + if (userHandle == null) { + userHandle = getIncomingUserHandle(); + } + ComponentName component = getDefaultMmsApplicationAsUser(context, false, - userId); + userHandle); if (component == null) { return false; } diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java index 76d2b7d8fce5..3dc71117ace8 100644 --- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java +++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java @@ -27,6 +27,8 @@ import android.os.Binder; import android.os.Bundle; import android.os.PersistableBundle; import android.os.SystemProperties; +import android.os.UserHandle; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import java.io.PrintWriter; @@ -212,4 +214,30 @@ public final class TelephonyUtils { return "UNKNOWN(" + mobileDataPolicy + ")"; } } -} + + /** + * Utility method to get user handle associated with this subscription. + * + * This method should be used internally as it returns null instead of throwing + * IllegalArgumentException or IllegalStateException. + * + * @param context Context object + * @param subId the subId of the subscription. + * @return userHandle associated with this subscription + * or {@code null} if: + * 1. subscription is not associated with any user + * 2. subId is invalid. + * 3. subscription service is not available. + * + * @throws SecurityException if the caller doesn't have permissions required. + */ + @Nullable + public static UserHandle getSubscriptionUserHandle(Context context, int subId) { + UserHandle userHandle = null; + SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class); + if ((subManager != null) && (SubscriptionManager.isValidSubscriptionId(subId))) { + userHandle = subManager.getSubscriptionUserHandle(subId); + } + return userHandle; + } +}
\ No newline at end of file diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java index 86b98f1cbe79..2435243f0044 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -5,6 +5,7 @@ import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.telecom.Connection; import android.telephony.data.ApnSetting; +import android.telephony.ims.ImsCallProfile; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -494,7 +495,7 @@ public class Annotation { PreciseCallState.PRECISE_CALL_STATE_HOLDING, PreciseCallState.PRECISE_CALL_STATE_DIALING, PreciseCallState.PRECISE_CALL_STATE_ALERTING, - PreciseCallState. PRECISE_CALL_STATE_INCOMING, + PreciseCallState.PRECISE_CALL_STATE_INCOMING, PreciseCallState.PRECISE_CALL_STATE_WAITING, PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED, PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING}) @@ -727,6 +728,36 @@ public class Annotation { }) public @interface ValidationStatus {} + /** + * IMS call Service types + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "SERVICE_TYPE_" }, value = { + ImsCallProfile.SERVICE_TYPE_NONE, + ImsCallProfile.SERVICE_TYPE_NORMAL, + ImsCallProfile.SERVICE_TYPE_EMERGENCY, + }) + public @interface ImsCallServiceType {} + + /** + * IMS call types + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "CALL_TYPE_" }, value = { + ImsCallProfile.CALL_TYPE_NONE, + ImsCallProfile.CALL_TYPE_VOICE_N_VIDEO, + ImsCallProfile.CALL_TYPE_VOICE, + ImsCallProfile.CALL_TYPE_VIDEO_N_VOICE, + ImsCallProfile.CALL_TYPE_VT, + ImsCallProfile.CALL_TYPE_VT_TX, + ImsCallProfile.CALL_TYPE_VT_RX, + ImsCallProfile.CALL_TYPE_VT_NODIR, + ImsCallProfile.CALL_TYPE_VS, + ImsCallProfile.CALL_TYPE_VS_TX, + ImsCallProfile.CALL_TYPE_VS_RX, + }) + public @interface ImsCallType {} + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "NET_CAPABILITY_ENTERPRISE_SUB_LEVEL" }, value = { diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java index b7bef39aa275..1dc64a9200fc 100644 --- a/telephony/java/android/telephony/CallAttributes.java +++ b/telephony/java/android/telephony/CallAttributes.java @@ -29,8 +29,10 @@ import java.util.Objects; * Contains information about a call's attributes as passed up from the HAL. If there are multiple * ongoing calls, the CallAttributes will pertain to the call in the foreground. * @hide + * @deprecated use {@link CallState} for call information for each call. */ @SystemApi +@Deprecated public final class CallAttributes implements Parcelable { private PreciseCallState mPreciseCallState; @NetworkType diff --git a/telephony/java/android/telephony/CallState.aidl b/telephony/java/android/telephony/CallState.aidl new file mode 100644 index 000000000000..dd5af8e65921 --- /dev/null +++ b/telephony/java/android/telephony/CallState.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +parcelable CallState; + diff --git a/telephony/java/android/telephony/CallState.java b/telephony/java/android/telephony/CallState.java new file mode 100644 index 000000000000..0a267cf0ff1f --- /dev/null +++ b/telephony/java/android/telephony/CallState.java @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Annotation.ImsCallServiceType; +import android.telephony.Annotation.ImsCallType; +import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.PreciseCallStates; +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsCallSession; + +import java.util.Objects; + +/** + * Contains information about various states for a call. + * @hide + */ +@SystemApi +public final class CallState implements Parcelable { + + /** + * Call classifications are just used for backward compatibility of deprecated API {@link + * TelephonyCallback#CallAttributesListener#onCallAttributesChanged}, Since these will be + * removed when the deprecated API is removed, they should not be opened. + */ + /** + * Call classification is not valid. It should not be opened. + * @hide + */ + public static final int CALL_CLASSIFICATION_UNKNOWN = -1; + + /** + * Call classification indicating foreground call + * @hide + */ + public static final int CALL_CLASSIFICATION_RINGING = 0; + + /** + * Call classification indicating background call + * @hide + */ + public static final int CALL_CLASSIFICATION_FOREGROUND = 1; + + /** + * Call classification indicating ringing call + * @hide + */ + public static final int CALL_CLASSIFICATION_BACKGROUND = 2; + + /** + * Call classification Max value. + * @hide + */ + public static final int CALL_CLASSIFICATION_MAX = CALL_CLASSIFICATION_BACKGROUND + 1; + + @PreciseCallStates + private final int mPreciseCallState; + + @NetworkType + private final int mNetworkType; // TelephonyManager.NETWORK_TYPE_* ints + private final CallQuality mCallQuality; + + private final int mCallClassification; + /** + * IMS call session ID. {@link ImsCallSession#getCallId()} + */ + @Nullable + private String mImsCallId; + + /** + * IMS call service type of this call + */ + @ImsCallServiceType + private int mImsCallServiceType; + + /** + * IMS call type of this call. + */ + @ImsCallType + private int mImsCallType; + + /** + * Constructor of CallAttributes + * + * @param callState call state defined in {@link PreciseCallState} + * @param networkType network type for this call attributes + * @param callQuality call quality for this call attributes, only CallState in + * {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE} will have valid call + * quality. + * @param callClassification call classification + * @param imsCallId IMS call session ID for this call attributes + * @param imsCallServiceType IMS call service type for this call attributes + * @param imsCallType IMS call type for this call attributes + */ + private CallState(@PreciseCallStates int callState, @NetworkType int networkType, + @NonNull CallQuality callQuality, int callClassification, @Nullable String imsCallId, + @ImsCallServiceType int imsCallServiceType, @ImsCallType int imsCallType) { + this.mPreciseCallState = callState; + this.mNetworkType = networkType; + this.mCallQuality = callQuality; + this.mCallClassification = callClassification; + this.mImsCallId = imsCallId; + this.mImsCallServiceType = imsCallServiceType; + this.mImsCallType = imsCallType; + } + + @NonNull + @Override + public String toString() { + return "mPreciseCallState=" + mPreciseCallState + " mNetworkType=" + mNetworkType + + " mCallQuality=" + mCallQuality + " mCallClassification" + mCallClassification + + " mImsCallId=" + mImsCallId + " mImsCallServiceType=" + mImsCallServiceType + + " mImsCallType=" + mImsCallType; + } + + private CallState(Parcel in) { + this.mPreciseCallState = in.readInt(); + this.mNetworkType = in.readInt(); + this.mCallQuality = in.readParcelable( + CallQuality.class.getClassLoader(), CallQuality.class); + this.mCallClassification = in.readInt(); + this.mImsCallId = in.readString(); + this.mImsCallServiceType = in.readInt(); + this.mImsCallType = in.readInt(); + } + + // getters + /** + * Returns the precise call state of the call. + */ + @PreciseCallStates + public int getCallState() { + return mPreciseCallState; + } + + /** + * Returns the {@link TelephonyManager#NetworkType} of the call. + * + * @see TelephonyManager#NETWORK_TYPE_UNKNOWN + * @see TelephonyManager#NETWORK_TYPE_GPRS + * @see TelephonyManager#NETWORK_TYPE_EDGE + * @see TelephonyManager#NETWORK_TYPE_UMTS + * @see TelephonyManager#NETWORK_TYPE_CDMA + * @see TelephonyManager#NETWORK_TYPE_EVDO_0 + * @see TelephonyManager#NETWORK_TYPE_EVDO_A + * @see TelephonyManager#NETWORK_TYPE_1xRTT + * @see TelephonyManager#NETWORK_TYPE_HSDPA + * @see TelephonyManager#NETWORK_TYPE_HSUPA + * @see TelephonyManager#NETWORK_TYPE_HSPA + * @see TelephonyManager#NETWORK_TYPE_IDEN + * @see TelephonyManager#NETWORK_TYPE_EVDO_B + * @see TelephonyManager#NETWORK_TYPE_LTE + * @see TelephonyManager#NETWORK_TYPE_EHRPD + * @see TelephonyManager#NETWORK_TYPE_HSPAP + * @see TelephonyManager#NETWORK_TYPE_GSM + * @see TelephonyManager#NETWORK_TYPE_TD_SCDMA + * @see TelephonyManager#NETWORK_TYPE_IWLAN + * @see TelephonyManager#NETWORK_TYPE_LTE_CA + * @see TelephonyManager#NETWORK_TYPE_NR + */ + @NetworkType + public int getNetworkType() { + return mNetworkType; + } + + /** + * Returns the {#link CallQuality} of the call. + * @return call quality for this call attributes, only CallState in {@link PreciseCallState# + * PRECISE_CALL_STATE_ACTIVE} will have valid call quality. It will be null for the + * call which is not in {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE}. + */ + @Nullable + public CallQuality getCallQuality() { + return mCallQuality; + } + + /** + * Returns the call classification. + * @hide + */ + public int getCallClassification() { + return mCallClassification; + } + + /** + * Returns the IMS call session ID. + */ + @Nullable + public String getImsCallSessionId() { + return mImsCallId; + } + + /** + * Returns the IMS call service type. + */ + @ImsCallServiceType + public int getImsCallServiceType() { + return mImsCallServiceType; + } + + /** + * Returns the IMS call type. + */ + @ImsCallType + public int getImsCallType() { + return mImsCallType; + } + + @Override + public int hashCode() { + return Objects.hash(mPreciseCallState, mNetworkType, mCallQuality, mCallClassification, + mImsCallId, mImsCallServiceType, mImsCallType); + } + + @Override + public boolean equals(@Nullable Object o) { + if (o == null || !(o instanceof CallState) || hashCode() != o.hashCode()) { + return false; + } + + if (this == o) { + return true; + } + + CallState s = (CallState) o; + + return (Objects.equals(mPreciseCallState, s.mPreciseCallState) + && mPreciseCallState == s.mPreciseCallState + && mNetworkType == s.mNetworkType + && Objects.equals(mCallQuality, s.mCallQuality) + && mCallClassification == s.mCallClassification + && Objects.equals(mImsCallId, s.mImsCallId) + && mImsCallType == s.mImsCallType + && mImsCallServiceType == s.mImsCallServiceType); + } + + /** + * {@link Parcelable#describeContents} + */ + public int describeContents() { + return 0; + } + + /** + * {@link Parcelable#writeToParcel} + */ + public void writeToParcel(@Nullable Parcel dest, int flags) { + dest.writeInt(mPreciseCallState); + dest.writeInt(mNetworkType); + dest.writeParcelable(mCallQuality, flags); + dest.writeInt(mCallClassification); + dest.writeString(mImsCallId); + dest.writeInt(mImsCallServiceType); + dest.writeInt(mImsCallType); + } + + public static final @NonNull Creator<CallState> CREATOR = new Creator() { + public CallState createFromParcel(Parcel in) { + return new CallState(in); + } + + public CallState[] newArray(int size) { + return new CallState[size]; + } + }; + + /** + * Builder of {@link CallState} + * + * <p>The example below shows how you might create a new {@code CallState}: + * + * <pre><code> + * + * CallState = new CallState.Builder() + * .setCallState(3) + * .setNetworkType({@link TelephonyManager#NETWORK_TYPE_LTE}) + * .setCallQuality({@link CallQuality}) + * .setImsCallSessionId({@link String}) + * .setImsCallServiceType({@link ImsCallProfile#SERVICE_TYPE_NORMAL}) + * .setImsCallType({@link ImsCallProfile#CALL_TYPE_VOICE}) + * .build(); + * </code></pre> + */ + public static final class Builder { + private @PreciseCallStates int mPreciseCallState; + private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + private CallQuality mCallQuality = null; + private int mCallClassification = CALL_CLASSIFICATION_UNKNOWN; + private String mImsCallId; + private @ImsCallServiceType int mImsCallServiceType = ImsCallProfile.SERVICE_TYPE_NONE; + private @ImsCallType int mImsCallType = ImsCallProfile.CALL_TYPE_NONE; + + + /** + * Default constructor for the Builder. + */ + public Builder(@PreciseCallStates int preciseCallState) { + mPreciseCallState = preciseCallState; + } + + /** + * Set network type of this call. + * + * @param networkType the transport type. + * @return The same instance of the builder. + */ + @NonNull + public CallState.Builder setNetworkType(@NetworkType int networkType) { + this.mNetworkType = networkType; + return this; + } + + /** + * Set the call quality {@link CallQuality} of this call. + * + * @param callQuality call quality of active call. + * @return The same instance of the builder. + */ + @NonNull + public CallState.Builder setCallQuality(@Nullable CallQuality callQuality) { + this.mCallQuality = callQuality; + return this; + } + + /** + * Set call classification for this call. + * + * @param classification call classification type defined in this class. + * @return The same instance of the builder. + * @hide + */ + @NonNull + public CallState.Builder setCallClassification(int classification) { + this.mCallClassification = classification; + return this; + } + + /** + * Set IMS call session ID of this call. + * + * @param imsCallId IMS call session ID. + * @return The same instance of the builder. + */ + @NonNull + public CallState.Builder setImsCallSessionId(@Nullable String imsCallId) { + this.mImsCallId = imsCallId; + return this; + } + + /** + * Set IMS call service type of this call. + * + * @param serviceType IMS call service type defined in {@link ImsCallProfile}. + * @return The same instance of the builder. + */ + @NonNull + public CallState.Builder setImsCallServiceType(@ImsCallServiceType int serviceType) { + this.mImsCallServiceType = serviceType; + return this; + } + + /** + * Set IMS call type of this call. + * + * @param callType IMS call type defined in {@link ImsCallProfile}. + * @return The same instance of the builder. + */ + @NonNull + public CallState.Builder setImsCallType(@ImsCallType int callType) { + this.mImsCallType = callType; + return this; + } + + /** + * Build the {@link CallState} + * + * @return the {@link CallState} object + */ + @NonNull + public CallState build() { + return new CallState( + mPreciseCallState, + mNetworkType, + mCallQuality, + mCallClassification, + mImsCallId, + mImsCallServiceType, + mImsCallType); + } + } +} diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 4ce2ca1d1045..5c1d4979031f 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -1663,17 +1663,33 @@ public class SubscriptionManager { } /** - * @return List of all SubscriptionInfo records in database, - * include those that were inserted before, maybe empty but not null. + * Get all subscription info records from SIMs that are inserted now or were inserted before. + * + * <p> + * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission, + * {@link SubscriptionInfo#getNumber()} will return empty string. + * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER}, + * {@link SubscriptionInfo#getIccId()} and {@link SubscriptionInfo#getCardString()} will return + * empty string, and {@link SubscriptionInfo#getGroupUuid()} will return {@code null}. + * + * <p> + * The carrier app will always have full {@link SubscriptionInfo} for the subscriptions + * that it has carrier privilege. + * + * @return List of all {@link SubscriptionInfo} records from SIMs that are inserted or + * inserted before. Sorted by {@link SubscriptionInfo#getSimSlotIndex()}, then + * {@link SubscriptionInfo#getSubscriptionId()}. + * * @hide */ + @RequiresPermission(anyOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + "carrier privileges", + }) @NonNull - @UnsupportedAppUsage public List<SubscriptionInfo> getAllSubscriptionInfoList() { - if (VDBG) logd("[getAllSubscriptionInfoList]+"); - List<SubscriptionInfo> result = null; - try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { @@ -3424,7 +3440,6 @@ public class SubscriptionManager { /** * Get subscriptionInfo list of subscriptions that are in the same group of given subId. - * See {@link #createSubscriptionGroup(List)} for more details. * * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE} * or carrier privilege permission on the subscription. @@ -4125,6 +4140,26 @@ public class SubscriptionManager { } /** + * Convert phone number source to string. + * + * @param source The phone name source. + * + * @return The phone name source in string format. + * + * @hide + */ + @NonNull + public static String phoneNumberSourceToString(@PhoneNumberSource int source) { + switch (source) { + case SubscriptionManager.PHONE_NUMBER_SOURCE_UICC: return "UICC"; + case SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER: return "CARRIER"; + case SubscriptionManager.PHONE_NUMBER_SOURCE_IMS: return "IMS"; + default: + return "UNKNOWN(" + source + ")"; + } + } + + /** * Convert display name source to string. * * @param source The display name source. diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index d3ddb1bf30a7..3024b896d1cf 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -71,6 +71,7 @@ import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemProperties; +import android.os.UserHandle; import android.os.WorkSource; import android.provider.Settings.SettingNotFoundException; import android.service.carrier.CarrierIdentifier; @@ -11934,8 +11935,9 @@ public class TelephonyManager { } /** - * Gets the default Respond Via Message application, updating the cache if there is no - * respond-via-message application currently configured. + * Get the component name of the default app to direct respond-via-message intent for the + * user associated with this subscription, update the cache if there is no respond-via-message + * application currently configured for this user. * @return component name of the app and class to direct Respond Via Message intent to, or * {@code null} if the functionality is not supported. * @hide @@ -11944,11 +11946,20 @@ public class TelephonyManager { @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS) @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING) public @Nullable ComponentName getAndUpdateDefaultRespondViaMessageApplication() { - return SmsApplication.getDefaultRespondViaMessageApplication(mContext, true); + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getDefaultRespondViaMessageApplication(getSubId(), true); + } + } catch (RemoteException e) { + Log.e(TAG, "Error in getAndUpdateDefaultRespondViaMessageApplication: " + e); + } + return null; } /** - * Gets the default Respond Via Message application. + * Get the component name of the default app to direct respond-via-message intent for the + * user associated with this subscription. * @return component name of the app and class to direct Respond Via Message intent to, or * {@code null} if the functionality is not supported. * @hide @@ -11957,7 +11968,15 @@ public class TelephonyManager { @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS) @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING) public @Nullable ComponentName getDefaultRespondViaMessageApplication() { - return SmsApplication.getDefaultRespondViaMessageApplication(mContext, false); + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getDefaultRespondViaMessageApplication(getSubId(), false); + } + } catch (RemoteException e) { + Log.e(TAG, "Error in getDefaultRespondViaMessageApplication: " + e); + } + return null; } /** diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index e6d7df34f755..1ea7fdc982a5 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -78,8 +78,9 @@ public final class ImsCallProfile implements Parcelable { public static final int SERVICE_TYPE_EMERGENCY = 2; /** - * Call types + * Call type none */ + public static final int CALL_TYPE_NONE = 0; /** * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade) */ diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index abf4cde62323..616ea50e4185 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.app.PendingIntent; +import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; import android.os.Bundle; @@ -2618,4 +2619,14 @@ interface ITelephony { * @hide */ boolean isRemovableEsimDefaultEuicc(String callingPackage); + + /** + * Get the component name of the default app to direct respond-via-message intent for the + * user associated with this subscription, update the cache if there is no respond-via-message + * application currently configured for this user. + * @return component name of the app and class to direct Respond Via Message intent to, or + * {@code null} if the functionality is not supported. + * @hide + */ + ComponentName getDefaultRespondViaMessageApplication(int subId, boolean updateIfNeeded); } diff --git a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java index 16f005f28856..591ffeb39721 100644 --- a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java +++ b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java @@ -42,6 +42,7 @@ import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.Set; /** * This test makes sure app installs with fs-verity signature, and on-access verification works. @@ -465,10 +466,10 @@ public class ApkVerityTest extends BaseHostJUnit4Test { break; } try { - CLog.d("lsof: " + expectRemoteCommandToSucceed("lsof " + apkPath)); + String openFiles = expectRemoteCommandToSucceed("lsof " + apkPath); + CLog.d("lsof: " + openFiles); Thread.sleep(1000); - String pid = expectRemoteCommandToSucceed("pidof system_server"); - mDevice.executeShellV2Command("kill -10 " + pid); // force GC + forceGCOnOpenFilesProcess(getOpenFilesPIDs(openFiles)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; @@ -478,6 +479,35 @@ public class ApkVerityTest extends BaseHostJUnit4Test { } } + /** + * This is a helper method that parses the lsof output to get PIDs of process holding FD. + * Here is an example output of lsof. This method extracts the second columns(PID). + * + * Example lsof output: + * COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME + * .example.app 1063 u0_a38 mem REG 253,6 8599 12826 example.apk + * .example.app 1063 u0_a38 99r REG 253,6 8599 12826 example.apk + */ + private Set<String> getOpenFilesPIDs(String lsof) { + Set<String> openFilesPIDs = new HashSet<>(); + String[] lines = lsof.split("\n"); + for (int i = 1; i < lines.length; i++) { + openFilesPIDs.add(lines[i].split("\\s+")[1]); + } + return openFilesPIDs; + } + + /** + * This is a helper method that forces GC on processes given their PIDs. + * That is to execute shell command "kill -10" on PIDs. + */ + private void forceGCOnOpenFilesProcess(Set<String> openFilesPIDs) + throws DeviceNotAvailableException { + for (String openFilePID : openFilesPIDs) { + mDevice.executeShellV2Command("kill -10 " + openFilePID); + } + } + private void verifyInstalledFiles(String... filenames) throws DeviceNotAvailableException { String apkPath = getApkPath(TARGET_PACKAGE); String appDir = apkPath.substring(0, apkPath.lastIndexOf("/")); diff --git a/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java b/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java index 5430dee5ca31..cfebf3462b57 100644 --- a/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java +++ b/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java @@ -19,8 +19,11 @@ package com.android.server.pm.dex; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assume.assumeFalse; + import android.app.UiAutomation; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Build; import android.os.ParcelFileDescriptor; import android.os.SystemClock; @@ -96,7 +99,12 @@ public final class DynamicCodeLoggerIntegrationTests { } @Before - public void primeEventLog() { + public void setup() { + assumeFalse(sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)); + primeEventLog(); + } + + private void primeEventLog() { // Force a round trip to logd to make sure everything is up to date. // Without this the first test passes and others don't - we don't see new events in the // log. The exact reason is unclear. diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp index a9fbfd97225d..81ec265c2c29 100644 --- a/tests/TelephonyCommonTests/Android.bp +++ b/tests/TelephonyCommonTests/Android.bp @@ -47,7 +47,7 @@ android_test { // Uncomment this and comment out the jarjar rule if you want to attach a debugger and step // through the renamed classes. - // platform_apis: true, + platform_apis: true, libs: [ "android.test.runner", diff --git a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java index 7a2af72c41d5..adefac64dbae 100644 --- a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java +++ b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java @@ -44,6 +44,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.content.res.Resources; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; @@ -75,9 +76,12 @@ import java.util.stream.Collectors; public class SmsApplicationTest { private static final ComponentName TEST_COMPONENT_NAME = ComponentName.unflattenFromString("com.android.test/.TestSmsApp"); + public static final String BLUETOOTH_PACKAGE_NAME = "com.android.bluetooth.services"; private static final String MMS_RECEIVER_NAME = "TestMmsReceiver"; private static final String RESPOND_VIA_SMS_NAME = "TestRespondViaSmsHandler"; private static final String SEND_TO_NAME = "TestSendTo"; + private static final String EXTERNAL_PROVIDER_CHANGE_NAME = "TestExternalProviderChangeHandler"; + private static final String SIM_FULL_NAME = "TestSimFullHandler"; private static final int SMS_APP_UID = 10001; private static final int FAKE_PHONE_UID = 10002; @@ -102,6 +106,7 @@ public class SmsApplicationTest { }).collect(Collectors.toSet()); @Mock private Context mContext; + @Mock private Resources mResources; @Mock private TelephonyManager mTelephonyManager; @Mock private RoleManager mRoleManager; @Mock private PackageManager mPackageManager; @@ -118,6 +123,9 @@ public class SmsApplicationTest { when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOpsManager); when(mContext.createContextAsUser(isNotNull(), anyInt())).thenReturn(mContext); + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getString(eq(com.android.internal.R.string.config_systemBluetoothStack))) + .thenReturn(BLUETOOTH_PACKAGE_NAME); doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) .when(mPackageManager) @@ -146,24 +154,46 @@ public class SmsApplicationTest { } } + @Test - public void testGetDefaultSmsApplication() { + public void testGetDefaultSmsApplicationAsUser() { assertEquals(TEST_COMPONENT_NAME, - SmsApplication.getDefaultSmsApplicationAsUser(mContext, false, 0)); + SmsApplication.getDefaultSmsApplicationAsUser(mContext, false, + UserHandle.SYSTEM)); } + @Test - public void testGetDefaultMmsApplication() { - assertEquals(TEST_COMPONENT_NAME, - SmsApplication.getDefaultMmsApplicationAsUser(mContext, false, - UserHandle.USER_SYSTEM)); + public void testGetDefaultMmsApplicationAsUser() { + ComponentName componentName = SmsApplication.getDefaultMmsApplicationAsUser(mContext, + false, UserHandle.SYSTEM); + assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName()); + assertEquals(MMS_RECEIVER_NAME, componentName.getClassName()); } @Test - public void testGetDefaultExternalTelephonyProviderChangedApplication() { - assertEquals(TEST_COMPONENT_NAME, - SmsApplication.getDefaultExternalTelephonyProviderChangedApplicationAsUser(mContext, - false, UserHandle.USER_SYSTEM)); + public void testGetDefaultExternalTelephonyProviderChangedApplicationAsUser() { + ComponentName componentName = SmsApplication + .getDefaultExternalTelephonyProviderChangedApplicationAsUser(mContext, + false, UserHandle.SYSTEM); + assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName()); + assertEquals(EXTERNAL_PROVIDER_CHANGE_NAME, componentName.getClassName()); + } + + @Test + public void testGetDefaultRespondViaMessageApplicationAsUserAsUser() { + ComponentName componentName = SmsApplication.getDefaultRespondViaMessageApplicationAsUser( + mContext, false, UserHandle.SYSTEM); + assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName()); + assertEquals(RESPOND_VIA_SMS_NAME, componentName.getClassName()); + } + + @Test + public void testGetDefaultSimFullApplicationAsUser() { + ComponentName componentName = SmsApplication.getDefaultSimFullApplicationAsUser(mContext, + false, UserHandle.SYSTEM); + assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName()); + assertEquals(SIM_FULL_NAME, componentName.getClassName()); } @Test @@ -174,7 +204,8 @@ public class SmsApplicationTest { setupPackageInfosForCoreApps(); assertEquals(TEST_COMPONENT_NAME, - SmsApplication.getDefaultSmsApplicationAsUser(mContext, true, 0)); + SmsApplication.getDefaultSmsApplicationAsUser(mContext, true, + UserHandle.SYSTEM)); verify(mAppOpsManager, atLeastOnce()).setUidMode(AppOpsManager.OPSTR_READ_SMS, SMS_APP_UID, AppOpsManager.MODE_ALLOWED); } @@ -251,6 +282,10 @@ public class SmsApplicationTest { return Collections.singletonList(makeRespondViaMessageResolveInfo()); case Intent.ACTION_SENDTO: return Collections.singletonList(makeSendToResolveInfo()); + case Telephony.Sms.Intents.ACTION_EXTERNAL_PROVIDER_CHANGE: + return Collections.singletonList(makeExternalProviderChangeResolveInfo()); + case Telephony.Sms.Intents.SIM_FULL_ACTION: + return Collections.singletonList(makeSimFullResolveInfo()); } return Collections.emptyList(); } @@ -308,4 +343,26 @@ public class SmsApplicationTest { info.activityInfo = activityInfo; return info; } + + private ResolveInfo makeExternalProviderChangeResolveInfo() { + ResolveInfo info = new ResolveInfo(); + ActivityInfo activityInfo = new ActivityInfo(); + + activityInfo.packageName = TEST_COMPONENT_NAME.getPackageName(); + activityInfo.name = EXTERNAL_PROVIDER_CHANGE_NAME; + + info.activityInfo = activityInfo; + return info; + } + + private ResolveInfo makeSimFullResolveInfo() { + ResolveInfo info = new ResolveInfo(); + ActivityInfo activityInfo = new ActivityInfo(); + + activityInfo.packageName = TEST_COMPONENT_NAME.getPackageName(); + activityInfo.name = SIM_FULL_NAME; + + info.activityInfo = activityInfo; + return info; + } } diff --git a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java new file mode 100644 index 000000000000..a62103e0030b --- /dev/null +++ b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony.tests; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.telephony.SubscriptionManager; + +import com.android.internal.telephony.util.TelephonyUtils; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +public class TelephonyUtilsTest { + @Rule + public final MockitoRule mockito = MockitoJUnit.rule(); + + // Mocked classes + @Mock + private Context mContext; + @Mock + private SubscriptionManager mSubscriptionManager; + + @Before + public void setup() { + doReturn(mSubscriptionManager).when(mContext) + .getSystemService(eq(SubscriptionManager.class)); + } + + + @Test + public void getSubscriptionUserHandle_subId_invalid() { + int invalidSubId = -10; + doReturn(false).when(mSubscriptionManager).isActiveSubscriptionId(eq(invalidSubId)); + + TelephonyUtils.getSubscriptionUserHandle(mContext, invalidSubId); + + // getSubscriptionUserHandle should not be called if subID is inactive. + verify(mSubscriptionManager, never()).getSubscriptionUserHandle(eq(invalidSubId)); + } + + @Test + public void getSubscriptionUserHandle_subId_valid() { + int activeSubId = 1; + doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(eq(activeSubId)); + + TelephonyUtils.getSubscriptionUserHandle(mContext, activeSubId); + + // getSubscriptionUserHandle should be called if subID is active. + verify(mSubscriptionManager, times(1)).getSubscriptionUserHandle(eq(activeSubId)); + } +} + + diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/ManualPermissionCheckDetector.kt b/tools/lint/checks/src/main/java/com/google/android/lint/aidl/ManualPermissionCheckDetector.kt deleted file mode 100644 index 2c53f390128c..000000000000 --- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/ManualPermissionCheckDetector.kt +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.lint.aidl - -import com.android.tools.lint.client.api.UElementHandler -import com.android.tools.lint.detector.api.Category -import com.android.tools.lint.detector.api.Detector -import com.android.tools.lint.detector.api.Implementation -import com.android.tools.lint.detector.api.Issue -import com.android.tools.lint.detector.api.JavaContext -import com.android.tools.lint.detector.api.Scope -import com.android.tools.lint.detector.api.Severity -import com.android.tools.lint.detector.api.SourceCodeScanner -import org.jetbrains.uast.UBlockExpression -import org.jetbrains.uast.UCallExpression -import org.jetbrains.uast.UElement -import org.jetbrains.uast.UIfExpression -import org.jetbrains.uast.UMethod -import org.jetbrains.uast.UQualifiedReferenceExpression - -/** - * Looks for methods implementing generated AIDL interface stubs - * that can have simple permission checks migrated to - * @EnforcePermission annotations - * - * TODO: b/242564870 (enable parse and autoFix of .aidl files) - */ -@Suppress("UnstableApiUsage") -class ManualPermissionCheckDetector : Detector(), SourceCodeScanner { - override fun getApplicableUastTypes(): List<Class<out UElement?>> = - listOf(UMethod::class.java) - - override fun createUastHandler(context: JavaContext): UElementHandler = AidlStubHandler(context) - - private inner class AidlStubHandler(val context: JavaContext) : UElementHandler() { - override fun visitMethod(node: UMethod) { - val interfaceName = getContainingAidlInterface(node) - .takeUnless(EXCLUDED_CPP_INTERFACES::contains) ?: return - val body = (node.uastBody as? UBlockExpression) ?: return - val fix = accumulateSimplePermissionCheckFixes(body) ?: return - - val javaRemoveFixes = fix.locations.map { - fix() - .replace() - .reformat(true) - .range(it) - .with("") - .autoFix() - .build() - } - - val javaAnnotateFix = fix() - .annotate(fix.annotation) - .range(context.getLocation(node)) - .autoFix() - .build() - - val message = - "$interfaceName permission check can be converted to @EnforcePermission annotation" - - context.report( - ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION, - fix.locations.last(), - message, - fix().composite(*javaRemoveFixes.toTypedArray(), javaAnnotateFix) - ) - } - - /** - * Walk the expressions in the method, looking for simple permission checks. - * - * If a single permission check is found at the beginning of the method, - * this should be migrated to @EnforcePermission(value). - * - * If multiple consecutive permission checks are found, - * these should be migrated to @EnforcePermission(allOf={value1, value2, ...}) - * - * As soon as something other than a permission check is encountered, stop looking, - * as some other business logic is happening that prevents an automated fix. - */ - private fun accumulateSimplePermissionCheckFixes(methodBody: UBlockExpression): - EnforcePermissionFix? { - val singleFixes = mutableListOf<EnforcePermissionFix>() - for (expression in methodBody.expressions) { - singleFixes.add(getPermissionCheckFix(expression) ?: break) - } - return when (singleFixes.size) { - 0 -> null - 1 -> singleFixes[0] - else -> EnforcePermissionFix.compose(singleFixes) - } - } - - /** - * If an expression boils down to a permission check, return - * the helper for creating a lint auto fix to @EnforcePermission - */ - private fun getPermissionCheckFix(startingExpression: UElement?): - EnforcePermissionFix? { - return when (startingExpression) { - is UQualifiedReferenceExpression -> getPermissionCheckFix( - startingExpression.selector - ) - - is UIfExpression -> getPermissionCheckFix(startingExpression.condition) - - is UCallExpression -> return EnforcePermissionFix - .fromCallExpression(context, startingExpression) - - else -> null - } - } - } - - companion object { - - private val EXPLANATION = """ - Whenever possible, method implementations of AIDL interfaces should use the @EnforcePermission - annotation to declare the permissions to be enforced. The verification code is then - generated by the AIDL compiler, which also takes care of annotating the generated java - code. - - This reduces the risk of bugs around these permission checks (that often become vulnerabilities). - It also enables easier auditing and review. - - Please migrate to an @EnforcePermission annotation. (See: go/aidl-enforce-howto) - """.trimIndent() - - @JvmField - val ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION = Issue.create( - id = "UseEnforcePermissionAnnotation", - briefDescription = "Manual permission check can be @EnforcePermission annotation", - explanation = EXPLANATION, - category = Category.SECURITY, - priority = 5, - severity = Severity.WARNING, - implementation = Implementation( - ManualPermissionCheckDetector::class.java, - Scope.JAVA_FILE_SCOPE - ), - enabledByDefault = false, // TODO: enable once b/241171714 is resolved - ) - } -} diff --git a/tools/lint/common/Android.bp b/tools/lint/common/Android.bp new file mode 100644 index 000000000000..898f88b8759c --- /dev/null +++ b/tools/lint/common/Android.bp @@ -0,0 +1,29 @@ +// Copyright (C) 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +java_library_host { + name: "AndroidCommonLint", + srcs: ["src/main/java/**/*.kt"], + libs: ["lint_api"], + kotlincflags: ["-Xjvm-default=all"], +} diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt index 3d5d01c9b7a0..3d5d01c9b7a0 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/Constants.kt +++ b/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt diff --git a/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt b/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt new file mode 100644 index 000000000000..720f8356f050 --- /dev/null +++ b/tools/lint/common/src/main/java/com/google/android/lint/PermissionMethodUtils.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.lint + +import com.android.tools.lint.detector.api.getUMethod +import org.jetbrains.uast.UCallExpression +import org.jetbrains.uast.UMethod +import org.jetbrains.uast.UParameter + +fun isPermissionMethodCall(callExpression: UCallExpression): Boolean { + val method = callExpression.resolve()?.getUMethod() ?: return false + return hasPermissionMethodAnnotation(method) +} + +fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations + .any { + it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD) + } + +fun hasPermissionNameAnnotation(parameter: UParameter) = parameter.annotations.any { + it.hasQualifiedName(ANNOTATION_PERMISSION_NAME) +} diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/model/Method.kt b/tools/lint/common/src/main/java/com/google/android/lint/model/Method.kt index 3939b6109eaa..3939b6109eaa 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/model/Method.kt +++ b/tools/lint/common/src/main/java/com/google/android/lint/model/Method.kt diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp new file mode 100644 index 000000000000..5f6c6f779f85 --- /dev/null +++ b/tools/lint/fix/Android.bp @@ -0,0 +1,28 @@ +// Copyright (C) 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +python_binary_host { + name: "lint_fix", + main: "lint_fix.py", + srcs: ["lint_fix.py"], +} diff --git a/tools/lint/Android.bp b/tools/lint/framework/Android.bp index 96618f413db1..7f27e8a57d19 100644 --- a/tools/lint/Android.bp +++ b/tools/lint/framework/Android.bp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Android Open Source Project +// Copyright (C) 2022 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,6 +29,11 @@ java_library_host { "auto_service_annotations", "lint_api", ], + static_libs: [ + "AndroidCommonLint", + // TODO: remove once b/236558918 is resolved and the below checks actually run globally + "AndroidGlobalLintChecker", + ], kotlincflags: ["-Xjvm-default=all"], } @@ -51,9 +56,3 @@ java_test_host { unit_test: true, }, } - -python_binary_host { - name: "lint_fix", - main: "fix/lint_fix.py", - srcs: ["fix/lint_fix.py"], -} diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt index 741655b402f2..413e19717d50 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt @@ -21,7 +21,7 @@ import com.android.tools.lint.client.api.Vendor import com.android.tools.lint.detector.api.CURRENT_API import com.google.android.lint.aidl.EnforcePermissionDetector import com.google.android.lint.aidl.EnforcePermissionHelperDetector -import com.google.android.lint.aidl.ManualPermissionCheckDetector +import com.google.android.lint.aidl.SimpleManualPermissionEnforcementDetector import com.google.android.lint.parcel.SaferParcelChecker import com.google.auto.service.AutoService @@ -40,7 +40,7 @@ class AndroidFrameworkIssueRegistry : IssueRegistry() { EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION, EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION, EnforcePermissionHelperDetector.ISSUE_ENFORCE_PERMISSION_HELPER, - ManualPermissionCheckDetector.ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION, + SimpleManualPermissionEnforcementDetector.ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION, SaferParcelChecker.ISSUE_UNSAFE_API_USAGE, PackageVisibilityDetector.ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS, RegisterReceiverFlagDetector.ISSUE_RECEIVER_EXPORTED_FLAG, diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt index 0c375c358e61..0c375c358e61 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingIdentityTokenDetector.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt index fe567da7c017..fe567da7c017 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsDetector.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt index 48540b1da565..48540b1da565 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt index 1b0f03564c3b..e12ec3d4a77c 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionMethodDetector.kt @@ -26,7 +26,6 @@ import com.android.tools.lint.detector.api.Scope import com.android.tools.lint.detector.api.Severity import com.android.tools.lint.detector.api.SourceCodeScanner import com.android.tools.lint.detector.api.getUMethod -import com.google.android.lint.aidl.hasPermissionMethodAnnotation import com.intellij.psi.PsiType import org.jetbrains.uast.UAnnotation import org.jetbrains.uast.UBlockExpression @@ -193,5 +192,8 @@ class PermissionMethodDetector : Detector(), SourceCodeScanner { else -> false } } + + private fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations + .any { it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD) } } } diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt index c3e0428316c3..c3e0428316c3 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt index 06c098df385d..06c098df385d 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/Method.kt index 0826e8e74431..0826e8e74431 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/Method.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt index f92826316be4..f92826316be4 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt index d90f3e31baf9..d90f3e31baf9 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt +++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingIdentityTokenDetectorTest.kt diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt index e72f38416310..e72f38416310 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt +++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/CallingSettingsNonUserGetterMethodsIssueDetectorTest.kt diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt index a70644ab8532..a70644ab8532 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt +++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt index b76342a81972..b76342a81972 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt +++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt index e686695ca804..e686695ca804 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt +++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt diff --git a/tools/lint/global/Android.bp b/tools/lint/global/Android.bp new file mode 100644 index 000000000000..3756abea2330 --- /dev/null +++ b/tools/lint/global/Android.bp @@ -0,0 +1,57 @@ +// Copyright (C) 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +java_library_host { + name: "AndroidGlobalLintChecker", + srcs: ["checks/src/main/java/**/*.kt"], + plugins: ["auto_service_plugin"], + libs: [ + "auto_service_annotations", + "lint_api", + ], + static_libs: ["AndroidCommonLint"], + kotlincflags: ["-Xjvm-default=all"], + dist: { + targets: ["droid"], + }, +} + +java_test_host { + name: "AndroidGlobalLintCheckerTest", + // TODO(b/239881504): Since this test was written, Android + // Lint was updated, and now includes classes that were + // compiled for java 15. The soong build doesn't support + // java 15 yet, so we can't compile against "lint". Disable + // the test until java 15 is supported. + enabled: false, + srcs: ["checks/src/test/java/**/*.kt"], + static_libs: [ + "AndroidGlobalLintChecker", + "junit", + "lint", + "lint_tests", + ], + test_options: { + unit_test: true, + }, +} diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt new file mode 100644 index 000000000000..b377d503f318 --- /dev/null +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.lint + +import com.android.tools.lint.client.api.IssueRegistry +import com.android.tools.lint.client.api.Vendor +import com.android.tools.lint.detector.api.CURRENT_API +import com.google.android.lint.aidl.EnforcePermissionDetector +import com.google.android.lint.aidl.EnforcePermissionHelperDetector +import com.google.android.lint.aidl.SimpleManualPermissionEnforcementDetector +import com.google.auto.service.AutoService + +@AutoService(IssueRegistry::class) +@Suppress("UnstableApiUsage") +class AndroidGlobalIssueRegistry : IssueRegistry() { + override val issues = listOf( + EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION, + EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION, + EnforcePermissionHelperDetector.ISSUE_ENFORCE_PERMISSION_HELPER, + SimpleManualPermissionEnforcementDetector.ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION, + ) + + override val api: Int + get() = CURRENT_API + + override val minApi: Int + get() = 8 + + override val vendor: Vendor = Vendor( + vendorName = "Android", + feedbackUrl = "http://b/issues/new?component=315013", + contact = "repsonsible-apis@google.com" + ) +}
\ No newline at end of file diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt new file mode 100644 index 000000000000..227cdcdc2fec --- /dev/null +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.lint.aidl + +import com.android.tools.lint.client.api.UElementHandler +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.SourceCodeScanner +import org.jetbrains.uast.UBlockExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UMethod + +/** + * Abstract class for detectors that look for methods implementing + * generated AIDL interface stubs + */ +abstract class AidlImplementationDetector : Detector(), SourceCodeScanner { + override fun getApplicableUastTypes(): List<Class<out UElement?>> = + listOf(UMethod::class.java) + + override fun createUastHandler(context: JavaContext): UElementHandler = AidlStubHandler(context) + + private inner class AidlStubHandler(val context: JavaContext) : UElementHandler() { + override fun visitMethod(node: UMethod) { + val interfaceName = getContainingAidlInterface(node) + .takeUnless(EXCLUDED_CPP_INTERFACES::contains) ?: return + val body = (node.uastBody as? UBlockExpression) ?: return + visitAidlMethod(context, node, interfaceName, body) + } + } + + abstract fun visitAidlMethod( + context: JavaContext, + node: UMethod, + interfaceName: String, + body: UBlockExpression, + ) +} diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt index 8ee3763e5079..8ee3763e5079 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/Constants.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt index bba819cd9096..bba819cd9096 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt index d120e1d41c99..f1b634898ec9 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionFix.kt @@ -19,6 +19,8 @@ package com.google.android.lint.aidl import com.android.tools.lint.detector.api.JavaContext import com.android.tools.lint.detector.api.Location import com.android.tools.lint.detector.api.getUMethod +import com.google.android.lint.hasPermissionNameAnnotation +import com.google.android.lint.isPermissionMethodCall import org.jetbrains.kotlin.psi.psiUtil.parameterIndex import org.jetbrains.uast.UCallExpression import org.jetbrains.uast.evaluateString diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt index 3c2ea1db0ad6..3c2ea1db0ad6 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt index edbdd8d2adf3..250ca78bae5e 100644 --- a/tools/lint/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt @@ -16,14 +16,9 @@ package com.google.android.lint.aidl -import com.android.tools.lint.detector.api.getUMethod -import com.google.android.lint.ANNOTATION_PERMISSION_METHOD -import com.google.android.lint.ANNOTATION_PERMISSION_NAME import com.google.android.lint.CLASS_STUB import com.intellij.psi.PsiAnonymousClass -import org.jetbrains.uast.UCallExpression import org.jetbrains.uast.UMethod -import org.jetbrains.uast.UParameter /** * Given a UMethod, determine if this method is @@ -51,17 +46,3 @@ private fun isInClassCalledStub(node: UMethod): Boolean { it.referenceName == CLASS_STUB } ?: false } - -fun isPermissionMethodCall(callExpression: UCallExpression): Boolean { - val method = callExpression.resolve()?.getUMethod() ?: return false - return hasPermissionMethodAnnotation(method) -} - -fun hasPermissionMethodAnnotation(method: UMethod): Boolean = method.annotations - .any { - it.hasQualifiedName(ANNOTATION_PERMISSION_METHOD) - } - -fun hasPermissionNameAnnotation(parameter: UParameter) = parameter.annotations.any { - it.hasQualifiedName(ANNOTATION_PERMISSION_NAME) -} diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt new file mode 100644 index 000000000000..4c0cbe7b3adf --- /dev/null +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.lint.aidl + +import com.android.tools.lint.detector.api.Category +import com.android.tools.lint.detector.api.Implementation +import com.android.tools.lint.detector.api.Issue +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.Scope +import com.android.tools.lint.detector.api.Severity +import org.jetbrains.uast.UBlockExpression +import org.jetbrains.uast.UCallExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UIfExpression +import org.jetbrains.uast.UMethod +import org.jetbrains.uast.UQualifiedReferenceExpression + +/** + * Looks for methods implementing generated AIDL interface stubs + * that can have simple permission checks migrated to + * @EnforcePermission annotations + * + * TODO: b/242564870 (enable parse and autoFix of .aidl files) + */ +@Suppress("UnstableApiUsage") +class SimpleManualPermissionEnforcementDetector : AidlImplementationDetector() { + override fun visitAidlMethod( + context: JavaContext, + node: UMethod, + interfaceName: String, + body: UBlockExpression + ) { + val fix = accumulateSimplePermissionCheckFixes(body, context) ?: return + + val javaRemoveFixes = fix.locations.map { + fix() + .replace() + .reformat(true) + .range(it) + .with("") + .autoFix() + .build() + } + + val javaAnnotateFix = fix() + .annotate(fix.annotation) + .range(context.getLocation(node)) + .autoFix() + .build() + + context.report( + ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION, + fix.locations.last(), + "$interfaceName permission check can be converted to @EnforcePermission annotation", + fix().composite(*javaRemoveFixes.toTypedArray(), javaAnnotateFix) + ) + } + + /** + * Walk the expressions in the method, looking for simple permission checks. + * + * If a single permission check is found at the beginning of the method, + * this should be migrated to @EnforcePermission(value). + * + * If multiple consecutive permission checks are found, + * these should be migrated to @EnforcePermission(allOf={value1, value2, ...}) + * + * As soon as something other than a permission check is encountered, stop looking, + * as some other business logic is happening that prevents an automated fix. + */ + private fun accumulateSimplePermissionCheckFixes( + methodBody: UBlockExpression, + context: JavaContext + ): + EnforcePermissionFix? { + val singleFixes = mutableListOf<EnforcePermissionFix>() + for (expression in methodBody.expressions) { + singleFixes.add(getPermissionCheckFix(expression, context) ?: break) + } + return when (singleFixes.size) { + 0 -> null + 1 -> singleFixes[0] + else -> EnforcePermissionFix.compose(singleFixes) + } + } + + /** + * If an expression boils down to a permission check, return + * the helper for creating a lint auto fix to @EnforcePermission + */ + private fun getPermissionCheckFix(startingExpression: UElement?, context: JavaContext): + EnforcePermissionFix? { + return when (startingExpression) { + is UQualifiedReferenceExpression -> getPermissionCheckFix( + startingExpression.selector, context + ) + + is UIfExpression -> getPermissionCheckFix(startingExpression.condition, context) + + is UCallExpression -> return EnforcePermissionFix + .fromCallExpression(context, startingExpression) + + else -> null + } + } + + companion object { + + private val EXPLANATION = """ + Whenever possible, method implementations of AIDL interfaces should use the @EnforcePermission + annotation to declare the permissions to be enforced. The verification code is then + generated by the AIDL compiler, which also takes care of annotating the generated java + code. + + This reduces the risk of bugs around these permission checks (that often become vulnerabilities). + It also enables easier auditing and review. + + Please migrate to an @EnforcePermission annotation. (See: go/aidl-enforce-howto) + """.trimIndent() + + @JvmField + val ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION = Issue.create( + id = "SimpleManualPermissionEnforcement", + briefDescription = "Manual permission check can be @EnforcePermission annotation", + explanation = EXPLANATION, + category = Category.SECURITY, + priority = 5, + severity = Severity.WARNING, + implementation = Implementation( + SimpleManualPermissionEnforcementDetector::class.java, + Scope.JAVA_FILE_SCOPE + ), + enabledByDefault = false, // TODO: enable once b/241171714 is resolved + ) + } +} diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt index 3c1d1e8e8a59..3c1d1e8e8a59 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt index 31e484628a04..31e484628a04 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/ManualPermissionCheckDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt index d4a34979ed9f..150fc264506f 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/ManualPermissionCheckDetectorTest.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt @@ -23,10 +23,10 @@ import com.android.tools.lint.detector.api.Detector import com.android.tools.lint.detector.api.Issue @Suppress("UnstableApiUsage") -class ManualPermissionCheckDetectorTest : LintDetectorTest() { - override fun getDetector(): Detector = ManualPermissionCheckDetector() +class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() { + override fun getDetector(): Detector = SimpleManualPermissionEnforcementDetector() override fun getIssues(): List<Issue> = listOf( - ManualPermissionCheckDetector + SimpleManualPermissionEnforcementDetector .ISSUE_USE_ENFORCE_PERMISSION_ANNOTATION ) @@ -52,7 +52,7 @@ class ManualPermissionCheckDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:7: Warning: ITest permission check can be converted to @EnforcePermission annotation [UseEnforcePermissionAnnotation] + src/Foo.java:7: Warning: ITest permission check can be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission("android.permission.READ_CONTACTS", "foo"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0 errors, 1 warnings @@ -92,7 +92,7 @@ class ManualPermissionCheckDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:8: Warning: ITest permission check can be converted to @EnforcePermission annotation [UseEnforcePermissionAnnotation] + src/Foo.java:8: Warning: ITest permission check can be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission( ^ 0 errors, 1 warnings @@ -132,7 +132,7 @@ class ManualPermissionCheckDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:8: Warning: ITest permission check can be converted to @EnforcePermission annotation [UseEnforcePermissionAnnotation] + src/Foo.java:8: Warning: ITest permission check can be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_CONTACTS, "foo"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0 errors, 1 warnings @@ -174,7 +174,7 @@ class ManualPermissionCheckDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:10: Warning: ITest permission check can be converted to @EnforcePermission annotation [UseEnforcePermissionAnnotation] + src/Foo.java:10: Warning: ITest permission check can be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission( ^ 0 errors, 1 warnings @@ -243,7 +243,7 @@ class ManualPermissionCheckDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:14: Warning: ITest permission check can be converted to @EnforcePermission annotation [UseEnforcePermissionAnnotation] + src/Foo.java:14: Warning: ITest permission check can be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] helper(); ~~~~~~~~~ 0 errors, 1 warnings @@ -289,7 +289,7 @@ class ManualPermissionCheckDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:16: Warning: ITest permission check can be converted to @EnforcePermission annotation [UseEnforcePermissionAnnotation] + src/Foo.java:16: Warning: ITest permission check can be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] mContext.enforceCallingOrSelfPermission("FOO", "foo"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0 errors, 1 warnings @@ -340,7 +340,7 @@ class ManualPermissionCheckDetectorTest : LintDetectorTest() { .run() .expect( """ - src/Foo.java:19: Warning: ITest permission check can be converted to @EnforcePermission annotation [UseEnforcePermissionAnnotation] + src/Foo.java:19: Warning: ITest permission check can be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement] helperHelper(); ~~~~~~~~~~~~~~~ 0 errors, 1 warnings diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt index bd6b1952847c..bd6b1952847c 100644 --- a/tools/lint/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp index 0d7d5f949a08..0fa13b81c4ea 100644 --- a/tools/validatekeymaps/Main.cpp +++ b/tools/validatekeymaps/Main.cpp @@ -167,8 +167,8 @@ static bool validateFile(const char* filename) { android::base::Result<std::unique_ptr<PropertyMap>> propertyMap = PropertyMap::load(String8(filename)); if (!propertyMap.ok()) { - error("Error %d parsing input device configuration file.\n\n", - propertyMap.error().code()); + error("Error parsing input device configuration file: %s.\n\n", + propertyMap.error().message().c_str()); return false; } break; |